标签:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<stack> 5 #include<vector> 6 using namespace std; 7 8 const int maxn=20005; 9 vector<int>G[maxn]; 10 stack<int>s; 11 int in[maxn],out[maxn],dfn[maxn],lowlink[maxn],sccno[maxn]; 12 int scc_cnt,dfs_clock; 13 int m,n; 14 15 void init() 16 { 17 for(int i=1;i<=n;i++)G[i].clear(); 18 memset(in,0,sizeof(in)); 19 memset(out,0,sizeof(out)); 20 memset(dfn,0,sizeof(dfn)); 21 memset(lowlink,0,sizeof(lowlink)); 22 memset(sccno,0,sizeof(sccno)); 23 scc_cnt=dfs_clock=0; 24 } 25 26 void tarjan(int u) 27 { 28 lowlink[u]=dfn[u]=++dfs_clock; 29 s.push(u); 30 for(int i=0;i<G[u].size();i++) 31 { 32 int v=G[u][i]; 33 if(!dfn[v]) 34 { 35 tarjan(v); 36 lowlink[u]=min(lowlink[u],lowlink[v]); 37 } 38 else if(!sccno[v]) 39 lowlink[u]=min(lowlink[u],dfn[v]); 40 } 41 if(lowlink[u]==dfn[u]) 42 { 43 scc_cnt++; 44 while(1) 45 { 46 int x=s.top(); 47 s.pop(); 48 sccno[x]=scc_cnt; 49 if(x==u)break; 50 } 51 } 52 } 53 54 int main() 55 { 56 int T; 57 scanf("%d",&T); 58 while(T--) 59 { 60 scanf("%d%d",&n,&m); 61 init(); 62 for(int i=0;i<m;i++) 63 { 64 int u,v; 65 scanf("%d%d",&u,&v); 66 G[u].push_back(v); 67 } 68 for(int i=1;i<=n;i++) 69 if(!dfn[i]) 70 tarjan(i); 71 for(int i=1;i<=n;i++) 72 for(int j=0;j<G[i].size();j++) 73 if(sccno[G[i][j]]!=sccno[i]) 74 { 75 in[sccno[G[i][j]]]++; 76 out[sccno[i]]++; 77 } 78 int cnt1=0,cnt2=0; 79 for(int i=1;i<=scc_cnt;i++) 80 { 81 if(!in[i]) 82 cnt1++; 83 if(!out[i]) 84 cnt2++; 85 } 86 if(scc_cnt==1) 87 puts("0"); 88 else 89 printf("%d\n",max(cnt1,cnt2)); 90 } 91 return 0; 92 }
HDU 2767 Proving Equivalences(强联通缩点)
标签:
原文地址:http://www.cnblogs.com/homura/p/4864864.html