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

浙公网安备 33010602011771号