题目链接: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 }
时间: 2024-10-14 17:05:01