huangriq

导航

poj 1904(强连通分量)

参考链接 

http://nightelf.sinaapp.com/2011/poj-1904-%E7%A1%AE%E5%AE%9A%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%88%86%E5%8C%B9%E9%85%8D%E7%9A%84%E6%89%80%E6%9C%89%E5%8F%AF%E8%83%BD%E8%BE%B9.html

题意:n个王子和n个美女要进行配对,每个王子可以喜欢若干个美女,但只能匹配其一个美女,求解每个王子能配对的美女使得其他王子也能成功配对,按升序输出王子能匹配的美女的编号。数据已经给出一个完备匹配。

建图:王子到每个喜欢的美女连一条有向边,在给出的完备匹配中由美女到王子连接一条有向边。构图后简化一下描述就是:如果从 A 点出发,最终能回到 A 点(成环)则能够维持完全匹配的,因此求一次强连通分量,判断每个王子与其喜欢的美女是否在同一强连通分量即可。

View Code
 1 #include<iostream>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<stack>
 9 using namespace std;
10 #define N 5005
11 vector<int> g[N];
12 stack<int> st;
13 int dfn[N],low[N],belg[N],in[N];
14 int c,indx;
15 void init(){
16     c=indx=1;
17     memset(dfn,0,sizeof(dfn));
18     memset(low,0,sizeof(low));
19     memset(belg,0,sizeof(belg));
20     memset(in,0,sizeof(in));
21     memset(g,0,sizeof(g));
22 }
23 void dfs(int u){
24     dfn[u]=low[u]=indx++;
25     in[u]=1;
26     st.push(u);
27     for(int i=0;i<g[u].size();i++){
28         int v=g[u][i];
29         if(!dfn[v]){
30             dfs(v);
31             low[u]=min(low[u],low[v]);
32         }
33         else if(in[v]){
34             low[u]=min(low[u],dfn[v]);
35         }
36     }
37     if(low[u]==dfn[u]){
38         while(1){
39             int v=st.top();
40             st.pop();
41             in[v]=0;
42             belg[v]=c;
43             if(v==u)break;
44         }
45         c++;
46     }
47 }
48 int main(){
49     int n;
50     while(scanf("%d",&n)!=EOF){
51         init();
52         for(int i=1;i<=n;i++){
53             int m;
54             scanf("%d",&m);
55             while(m--){
56                 int x;
57                 scanf("%d",&x);
58                 g[i].push_back(x+n);
59             }
60         }
61         for(int i=1;i<=n;i++){
62             int x;
63             scanf("%d",&x);
64             g[x+n].push_back(i);
65         }
66         for(int i=1;i<=n;i++){
67             if(!dfn[i])dfs(i);
68         }
69         for(int i=1;i<=n;i++){
70             priority_queue<int ,vector<int> ,greater<int> > q;
71             for(int j=0;j<g[i].size();j++){
72                 int v=g[i][j];
73                 if(belg[i]==belg[v])q.push(v-n);
74             }
75             printf("%d",q.size());
76             while(!q.empty()){
77                 printf(" %d",q.top());
78                 q.pop();
79             }
80             printf("\n");
81         }
82     }
83     return 0;
84 }

 

posted on 2012-07-29 10:41  huangriq  阅读(181)  评论(0编辑  收藏  举报