標籤:style blog http color os io for 2014
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 }