山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

UVAlive4287 Proving Equivalences(scc)

 

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10294

 

【思路】

       强连通分量。

       求出bcc后,缩点形成DAG,设DAG上入度为0的点数为a 出度为0的点数为b,则ans=max(a,b) (互相到达,首尾相接),需要注意scc数为1的时候ans=0。

 

【代码】

 

 1 #include<cstdio>
 2 #include<stack>
 3 #include<vector>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 const int maxn = 20000+10;
 9 
10 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
11 vector<int> G[maxn];
12 stack<int> S;
13 
14 int dfs(int u) {
15     pre[u]=lowlink[u]=++dfs_clock;
16     S.push(u);
17     for(int i=0;i<G[u].size();i++) {
18         int v=G[u][i];
19         if(!pre[v]) {
20             dfs(v);
21             lowlink[u]=min(lowlink[u],lowlink[v]);
22         }
23         else if(!sccno[v]) {
24             lowlink[u]=min(lowlink[u],pre[v]);
25         }
26     }
27     if(lowlink[u]==pre[u]) {
28         scc_cnt++;
29         for(;;) {
30             int x=S.top(); S.pop();
31             sccno[x]=scc_cnt;
32             if(x==u) break;
33         }
34     }
35 }
36 void find_scc(int n) {
37     memset(pre,0,sizeof(pre));
38     memset(sccno,0,sizeof(sccno));
39     scc_cnt=dfs_clock=0;
40     for(int i=0;i<n;i++)  
41     if(!pre[i]) dfs(i);
42 }
43 
44 int T,n,m;
45 int in0[maxn],out0[maxn];
46 
47 int main() {
48     scanf("%d",&T);
49     while(T--) {
50         scanf("%d%d",&n,&m);
51         for(int i=0;i<n;i++) G[i].clear();
52         int u,v;
53         for(int i=0;i<m;i++) {
54             scanf("%d%d",&u,&v);
55             u--,v--;
56             G[u].push_back(v);
57         }
58         find_scc(n);
59         for(int i=1;i<=scc_cnt;i++) in0[i]=out0[i]=1;
60         for(int i=0;i<n;i++) {
61             int u=sccno[i];
62             for(int j=0;j<G[i].size();j++) {
63                 int v=sccno[G[i][j]];
64                 if(u!=v) out0[u]=in0[v]=0;
65             }
66         }
67         int a=0,b=0;
68         for(int i=1;i<=scc_cnt;i++)
69             a+=in0[i],b+=out0[i];
70         int ans=scc_cnt==1? 0:max(a,b);
71         printf("%d\n",ans);
72     }
73     return 0;
74 }

 

posted on 2015-12-18 07:59  hahalidaxin  阅读(222)  评论(0编辑  收藏  举报