首页 > 代码库 > poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)
poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)
1 /* 2 题目大意:有N个cows, M个关系 3 a->b 表示 a认为b popular;如果还有b->c, 那么就会有a->c 4 问最终有多少个cows被其他所有cows认为是popular! 5 6 思路:强连通分量中每两个节点都是可达的! 通过分解得到最后一个连通分量A, 7 如果将所有的强连通分量看成一个大的节点,那么A一定是孩子节点(因为我们先 8 完成的是父亲节点的强连通分量)! 最后如果其他的强连通分量都可以指向A,那么 9 A中的每一个cow都会被其他cows所有的cows认为popular! 10 */ 11 #include <string>12 #include <cstdio>13 #include <cstring>14 #include <iostream>15 #include<vector>16 #define M 1000517 using namespace std;18 19 vector<int>ex[M];20 vector<int>ey[M];21 22 int n, m;23 int cnt[M];//记录第一次dfs的节点的逆序24 int vis[M];//标记节点是否已经被访问过了25 int mark[M];//标记每一个节点是属于哪一个连通分量26 int ans;27 int top;28 29 void dfs1(int u){//出度遍历 30 if(!vis[u]){31 vis[u]=1;32 int len=ex[u].size();33 for(int i=0; i<len; ++i){34 int v=ex[u][i];35 dfs1(v);36 }37 cnt[top++]=u;38 }39 }40 41 void dfs2(int u){//入度遍历 42 if(!vis[u]){43 vis[u]=1;44 mark[u]=ans;45 int len=ey[u].size();46 for(int i=0; i<len; ++i){47 int v=ey[u][i];48 dfs2(v);49 }50 }51 }52 53 int main(){54 while(scanf("%d%d", &n, &m)!=EOF){55 while(m--){56 int u, v;57 scanf("%d%d", &u, &v);58 ex[u].push_back(v);59 ey[v].push_back(u);60 }61 ans=top=0;62 for(int i=1; i<=n; ++i)63 if(!vis[i])64 dfs1(i);65 66 memset(vis, 0, sizeof(vis));67 68 for(int i=top-1; i>=0; --i)69 if(!vis[cnt[i]]){70 ++ans;71 dfs2(cnt[i]);72 }73 int count=0;74 int u=0;75 for(int i=1; i<=n; ++i)76 if(mark[i]==ans){77 ++count;78 u=i;79 }80 memset(vis, 0, sizeof(vis));81 dfs2(u);82 83 for(int i=1; i<=n; ++i)//其他的强连通分量是否都指向了最后一个强连通分量 84 if(!vis[i]){85 count=0;86 break;87 }88 printf("%d\n", count);89 for(int i=1; i<=n; ++i){90 ex[i].clear();91 ey[i].clear();92 }93 memset(vis, 0, sizeof(vis));94 }95 return 0;96 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。