King's Quest

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

题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配,匹配有n个数,代表某个儿子和哪个女孩可以结婚,已知这些条件,要你找出每个儿子可以和哪些女孩结婚

题解:首先儿子和喜欢女孩建一条边,然后最后的女孩和儿子建一条边,然后缩点就可以了,至于为什么这么做,还在研究当中。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<set>
 7 using namespace std;
 8 vector<int>ans;
 9 const int N=4000+30;
10 const int M=400010;
11 const int INF=0xffffffff;
12 struct Edge{
13     int to,next;
14 } edge[M];
15 int  n,m,temp,cnt,dep,top,atype;
16 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
17 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
18 void init(){
19       cnt=dep=top=atype=0;
20     memset(head,-1,sizeof(head));
21     memset(dfn,0,sizeof(dfn));
22     memset(low,0,sizeof(low));
23     memset(vis,0,sizeof(vis));
24     memset(belong,0,sizeof(belong));
25     memset(in,0,sizeof(in));
26     memset(out,0,sizeof(out));
27     memset(sum,0,sizeof(sum));
28 }
29 void addedge(int u,int v){
30     edge[cnt].to=v;
31     edge[cnt].next=head[u];
32     head[u]=cnt++;
33 }
34 
35 void Tarjan(int u){
36     dfn[u]=low[u]=++dep;
37     st[top++]=u;
38     vis[u]=1;
39     for(int i=head[u]; i!=-1; i=edge[i].next){
40         int v=edge[i].to;
41         if(!dfn[v]){
42             Tarjan(v);
43             low[u]=min(low[u],low[v]);
44         }
45         else if(vis[v]){
46             low[u]=min(low[u],dfn[v]);
47         }
48     }
49     int j;
50     if(dfn[u]==low[u]){
51         atype++;
52         do{
53             j=st[--top];
54             belong[j]=atype;
55             sum[atype]++;   //记录每个连通分量中点的个数
56             vis[j]=0;
57         }
58         while(u!=j);
59     }
60 }
61 int main(){
62      while(~scanf("%d",&n)){
63         init();
64         for(int i=1;i<=n;i++){
65             scanf("%d",&m);
66             for(int j=1;j<=m;j++){
67                 scanf("%d",&temp);
68                 addedge(i,temp+n);
69             }
70         }
71         for(int i=1;i<=n;i++){
72             scanf("%d",&temp);
73             addedge(temp+n,i);
74         }
75         for(int i=1;i<=2*n;i++)
76             if(!dfn[i])
77             Tarjan(i);
78         for(int i=1;i<=n;i++){
79             ans.clear();
80             for(int j=head[i];j!=-1;j=edge[j].next){
81                 int v=edge[j].to;
82             if(belong[i]==belong[v])
83                 ans.push_back(v-n);
84             }
85             int sz=ans.size();
86             sort(ans.begin(),ans.end());
87             printf("%d",sz);
88             for(int j=0;j<sz;j++){
89                 printf(" %d",ans[j]);
90             }
91             puts("");
92         }
93      }
94 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3919078.html