[POJ2186]Popular Cows(强连通分量)

题目链接:http://poj.org/problem?id=2186

给定n个点m条边,求某点使得其他点都有通向它的一条路径,计算这个点集的大小。

强连通分解后求出度为0的连通分量的个数,如果有且仅有一个连通分量出度为1,则统计这个连通分量中点的数目。

遍历所有点的出边指向的点,判断这两个点是否属于同一个连通分量,记录每个连通分量中的点的数目。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19 
 20 using namespace std;
 21 
 22 const int maxn = 11111;
 23 typedef struct Edge {
 24     int v;
 25     int next;
 26     Edge() { next = -1; }
 27 }Edge;
 28 
 29 int head[maxn], ecnt;
 30 Edge edge[55555];
 31 int n, m;
 32 
 33 int bcnt, dindex;
 34 int dfn[maxn], low[maxn];
 35 int stk[maxn], top;
 36 int belong[maxn];
 37 bool instk[maxn];
 38 int dig[maxn];
 39 
 40 void init() {
 41     memset(edge, 0, sizeof(edge));
 42     memset(head, -1, sizeof(head));
 43     memset(instk, 0, sizeof(instk));
 44     memset(dfn, 0, sizeof(dfn));
 45     memset(low, 0, sizeof(low));
 46     memset(belong, 0, sizeof(belong));
 47     memset(dig, 0, sizeof(dig));
 48     ecnt = top = bcnt = dindex = 0;
 49 }
 50 
 51 void adde(int uu, int vv) {
 52     edge[ecnt].v = vv;
 53     edge[ecnt].next = head[uu];
 54     head[uu] = ecnt++;
 55 }
 56 
 57 void tarjan(int u) {
 58     int v = u;
 59     dfn[u] = low[u] = ++dindex;
 60     stk[++top] = u;
 61     instk[u] = 1;
 62     for(int i = head[u]; ~i; i=edge[i].next) {
 63         v = edge[i].v;
 64         if(!dfn[v]) {
 65             tarjan(v);
 66             low[u] = min(low[u], low[v]);
 67         }
 68         else if(instk[v] && dfn[v] < low[u]) {
 69             low[u] = dfn[v];
 70         }
 71     }
 72     if(dfn[u] == low[u]) {
 73         bcnt++;
 74         do {
 75             v = stk[top--];
 76             instk[v] = 0;
 77             belong[v] = bcnt;
 78         } while(v != u && top != 0);
 79     }
 80 }
 81 
 82 int main() {
 83     // freopen("in", "r", stdin);
 84     int uu, vv;
 85     while(~scanf("%d %d", &n, &m)) {
 86         init();
 87         for(int i = 0; i < m; i++) {
 88             scanf("%d %d", &uu, &vv);
 89             adde(uu, vv);
 90         }
 91         for(int i = 1; i <= n; i++) {
 92             if(!dfn[i]) {
 93                 tarjan(i);
 94             }
 95         }
 96         for(int i = 1; i <= n; i++) {
 97             for(int j = head[i]; ~j; j = edge[j].next) {
 98                 if(belong[i] != belong[edge[j].v]) {
 99                     dig[belong[i]]++;
100                 }
101             }
102         }
103         int tmp, cnt = 0, ans = 0;
104           for(int i = 1; i <= bcnt; i++) {
105               if(!dig[i]) {
106                   cnt++;
107                   tmp = i;
108               }
109         }
110           if(cnt == 1) {
111               for(int i = 1; i <= n; i++) {
112                   if(belong[i] == tmp) {
113                       ans++;
114                   }
115               }
116               printf("%d\n", ans);
117           }
118           else {
119               printf("0\n");
120           }
121     }
122     return 0;
123 }

 

posted @ 2016-03-07 11:57  Kirai  阅读(177)  评论(0编辑  收藏  举报