题目链接:

http://poj.org/problem?id=1904

题意:

有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配。

题解:

1、建图:

如果王子u对公主v心仪,则连一条边u->v。在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u。

2、求强连通分量:

如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主。

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<stack>
#include<vector>
#include<cstring>
using namespace std; const int maxn=; int N; struct Edge{
int v,ne;
Edge(int v,int ne):v(v),ne(ne){}
Edge(){}
}egs[+maxn]; int head[maxn],tot; void addEdge(int u,int v){
egs[tot]=Edge(v,head[u]);
head[u]=tot++;
} int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
stack<int> S; int scan(){
int ret=,flag=; char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') ret=ch-'';
while((ch=getchar())>=''&&ch<='') ret=ret*+ch-'';
return flag?-ret:ret;
} void out(int x){
if(x>) out(x/);
putchar(x%+'');
} void dfs(int u){
pre[u]=lowlink[u]=++dfs_clock;
S.push(u);
for(int i=head[u];i!=-;i=egs[i].ne){
Edge& e=egs[i];
int v=e.v;
if(!pre[v]){
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}else if(!sccno[v]){
lowlink[u]=min(lowlink[u],pre[v]);
}
}
if(lowlink[u]==pre[u]){
scc_cnt++;
for(;;){
int x=S.top(); S.pop();
sccno[x]=scc_cnt;
if(x==u) break;
}
}
} void find_scc(int n){
dfs_clock=scc_cnt=;
memset(sccno,,sizeof(sccno));
memset(pre,,sizeof(pre));
for(int i=;i<n;i++){
if(!pre[i]) dfs(i);
}
} void build(){
int cnt,v;
for(int i=;i<N;i++){
cnt=scan();
while(cnt--){
v=scan(); v--;
addEdge(i,v+N);
}
}
for(int i=;i<N;i++){
v=scan(); v--;
addEdge(v+N,i);
}
} void init(){
memset(head,-,sizeof(head));
tot=;
} int ans[],t; int main(){
while(scanf("%d",&N)==&&N){
init();
build();
find_scc(*N);
for(int i=;i<N;i++){
t=;
for(int j=head[i];j!=-;j=egs[j].ne){
Edge& e=egs[j];
int v=e.v;
if(sccno[i]==sccno[v]) ans[t++]=v;
}
sort(ans,ans+t);
out(t);
for(int i=;i<t;i++){
putchar(' ');
out(ans[i]+-N);
}
putchar('\n');
}
}
return ;
}

Poj 1904 King's Quest 强连通分量的更多相关文章

  1. POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)

    题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...

  2. POJ 1904 King's Quest (强连通分量+完美匹配)

    <题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...

  3. POJ 1904 King's Quest 强连通分量+二分图增广判定

    http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #inc ...

  4. POJ - 1904 King's Quest (强连通)

    题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...

  5. [poj 1904]King's Quest[Tarjan强连通分量]

    题意:(当时没看懂...) N个王子和N个女孩, 每个王子喜欢若干女孩. 给出每个王子喜欢的女孩编号, 再给出一种王子和女孩的完美匹配. 求每个王子分别可以和那些女孩结婚可以满足最终每个王子都能找到一 ...

  6. POJ 1904 King's Quest tarjan

    King's Quest 题目连接: http://poj.org/problem?id=1904 Description Once upon a time there lived a king an ...

  7. poj 1904 King's Quest

    King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每 ...

  8. POJ 1904 King's Quest(SCC的巧妙应用,思维题!!!,经典题)

    King's Quest Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 10305   Accepted: 3798 Ca ...

  9. poj 1904 King's Quest tarjan求二分图的所有可选最大匹配边

    因为是完美匹配,所以每个点都已经匹配了,那么如果要选择一条别的边,增光路的最后必定找到原来所匹配的点,加上匹配的边,那么就是一个环.所以可选边在一个强连通分量里. #include <iostr ...

随机推荐

  1. win7 C# winForm编程 savefiledialog 不能弹出保存窗体

    public void ResMsg()        {            while (isRecMsg)            {                //准备一个数组 准备接收 ...

  2. c#获取多个List<class>合并、并将相同条件下的值累计sum

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. 安装Google框架服务并突破Google Play下载限制

    请注明出处:http://www.cnblogs.com/killerlegend/p/3546235.html Written By KillerLegend 关于谷歌服务框架以及安装 安装前请先获 ...

  4. FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...

  5. 第十一章 管理类型(In .net4.5) 之 管理对象的生命周期

    1. 概述 本章内容包括 管理非托管资源.使用IDisposable接口 以及 管理析构器和垃圾回收. 2. 主要内容 2.1 理解垃圾回收机制 ① 代码执行的时候,内存中有两个地方存放数据项:堆 和 ...

  6. Collection、Iterator、Set、HashSet

    Collection接口的基本方法 boolean add(Object o) 向集合当中加入一个对象 void clear() 删除集合当中的所有对象 boolean isEmpty() 判断集合是 ...

  7. ED/EP系列7《指令速查表》

    命 令                                                             CLA                  INS             ...

  8. 教你怎么安装Redis

    以下命令以root用户运行:#cd /tmp/#wget http://redis.googlecode.com/files/redis-2.6.11.tar.gz#tar xzf redis-2.6 ...

  9. IOS内存管理「2」- 点语法的内存管理

  10. PHP中使用CURL实现GET和POST请求

    转自:http://www.smsyun.com/home-index-page-id-284.html 一.什么是CURL? cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议, ...