Poj--2186(强连通分量,缩点)

2014-10-14 22:55:29

思路:典型的SCC问题,直接强连通+缩点,搞出DAG后我们发现,如果某个点k满足:除k外其他所有点都能到达k,那么k这个scc里的牛都是popular的。换句话说k这个点是DAG的终点,所以只要找出出度为零的点即可。(注意要判断出度为零的点的个数,>1的话说明DAG不连通,答案当然是0)

  1 /*************************************************************************
  2     > File Name: 2186.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com 
  5     > Created Time: Tue 14 Oct 2014 10:35:22 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <map>
 14 #include <set>
 15 #include <stack>
 16 #include <queue>
 17 #include <iostream>
 18 #include <algorithm>
 19 using namespace std;
 20 #define lp (p << 1)
 21 #define rp (p << 1|1)
 22 #define getmid(l,r) (l + (r - l) / 2)
 23 #define MP(a,b) make_pair(a,b)
 24 typedef long long ll;
 25 const int INF = 1 << 30;
 26 const int maxn = 10010;
 27 
 28 int N,M;
 29 int first[maxn],next[maxn * 5],ver[maxn * 5],ecnt;
 30 int low[maxn],dfn[maxn],sc[maxn],tot,scnt;
 31 int f1[maxn],n1[maxn * 5],v1[maxn * 5],e1;
 32 int cnt[maxn],dout[maxn];
 33 stack<int> S;
 34 
 35 void Init(){
 36     memset(first,-1,sizeof(first));
 37     memset(f1,-1,sizeof(f1));
 38     memset(cnt,0,sizeof(cnt));
 39     ecnt = tot = scnt = 0;
 40     e1 = 0;
 41 }
 42 
 43 void Add_edge(int u,int v){
 44     next[++ecnt] = first[u];
 45     ver[ecnt] = v;
 46     first[u] = ecnt;
 47 }
 48 
 49 void Dfs(int p){
 50     low[p] = dfn[p] = ++tot;
 51     S.push(p);
 52     for(int i = first[p]; i != -1; i = next[i]){
 53         int v = ver[i];
 54         if(!dfn[v]){
 55             Dfs(v);
 56             low[p] = min(low[p],low[v]);
 57         }
 58         else if(!sc[v]){
 59             low[p] = min(low[p],dfn[v]);
 60         }
 61     }
 62     if(low[p] == dfn[p]){
 63         ++scnt;
 64         while(1){
 65             int x = S.top();
 66             S.pop();
 67             sc[x] = scnt;
 68             cnt[scnt]++;
 69             if(x == p) break;
 70         }
 71     }
 72 }
 73 
 74 void Tarjan(){
 75     memset(low,0,sizeof(low));
 76     memset(dfn,0,sizeof(dfn));
 77     memset(sc,0,sizeof(sc));
 78     while(!S.empty()) S.pop();
 79     for(int i = 1; i <= N; ++i)
 80         if(!dfn[i]) Dfs(i);
 81 }
 82 
 83 void Add_edge1(int u,int v){
 84     n1[++e1] = f1[u];
 85     v1[e1] = v;
 86     f1[u] = e1;
 87 }
 88 
 89 int main(){
 90     int a,b;
 91     scanf("%d%d",&N,&M);
 92     Init();
 93     for(int i = 1; i <= M; ++i){
 94         scanf("%d%d",&a,&b);
 95         Add_edge(a,b);
 96     }
 97     Tarjan();
 98     for(int k = 1; k <= N; ++k){
 99         for(int i = first[k]; i != -1; i = next[i]){
100             int v = ver[i];
101             if(sc[k] != sc[v]){
102                 dout[sc[k]]++;
103             }
104         }
105     }
106     int c = 0,p;
107     for(int i = 1; i <= scnt; ++i){
108         if(dout[i] == 0){
109             c++;
110             p = i;
111         }
112     }
113     if(c == 1) printf("%d\n",cnt[p]);
114     else printf("0\n");
115     return 0;
116 }
117     

 

posted @ 2014-10-14 22:59  Naturain  阅读(164)  评论(0)    收藏  举报