1. 程式人生 > >poj 2186 強連通入門題目

poj 2186 強連通入門題目

LV top truct AS con pan n) 就是 turn

每頭牛的夢想就是成為牛群中最受歡迎的牛。 在一群N(1 <= N <= 10,000)母牛中,

你可以得到M(1 <= M <= 50,000)有序的形式對(A,B),告訴你母牛A認為母牛 B很受歡迎。

由於流行是傳遞性的,如果A認為B很受歡迎,B認為C受歡迎,那麽A也會認為C是
流行的,即使這不是輸入中有序對明確規定的。

你的任務是計算每頭奶牛認為受歡迎的奶牛數量。

水題 強連通入門題目。

tarjin縮點 然後就變成一棵樹,

然後就是求有多少個點的出度為0

輸入這個點裏面包含的所有點,因為有縮點出來的

所有輸出他的強連通分量

縮點後如果有多個出度為0的點,這樣是不符合題意的,輸出0

不聯通 也是輸出0

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 
 8 const int maxn = 1e5 + 10;
 9 int n, m, u, v, tot, top, cnt, flag;
10 struct node {
11     int v, next;
12 } edge[maxn];
13 int head[maxn], instack[maxn], s[maxn]; 14 int dfn[maxn], low[maxn], belong[maxn]; 15 void init() { 16 tot = cnt = top = flag = 0; 17 memset(head, -1, sizeof(head)); 18 memset(dfn, 0, sizeof(dfn)); 19 memset(instack, 0, sizeof(instack)); 20 } 21 void add(int u, int v) { 22 edge[tot].v = v;
23 edge[tot].next = head[u]; 24 head[u] = tot++; 25 } 26 void tarjin(int v) { 27 dfn[v] = low[v] = ++flag; 28 instack[v] = 1; 29 s[top++] = v; 30 for (int i = head[v] ; i != -1 ; i = edge[i].next) { 31 int j = edge[i].v; 32 if (!dfn[j]) { 33 tarjin(j); 34 low[v] = min(low[v], low[j]); 35 } else if (instack[j]) low[v] = min(low[v], dfn[j]); 36 } 37 if (dfn[v] == low[v]) { 38 cnt++; 39 int t; 40 do { 41 t = s[--top]; 42 instack[t] = 0; 43 belong[t] = cnt; 44 } while(t != v) ; 45 } 46 } 47 int du[maxn]; 48 void solve() { 49 for (int i = 1 ; i <= n ; i++) 50 if (!dfn[i]) tarjin(i); 51 } 52 int main() { 53 while(scanf("%d%d", &n, &m) != EOF) { 54 if (n == 0 && m == 0) break; 55 init(); 56 memset(du, 0, sizeof(du)); 57 for (int i = 0 ; i < m ; i++) { 58 scanf("%d%d", &u, &v); 59 add(u, v); 60 } 61 for (int i = 1 ; i <= n ; i++) 62 if (!dfn[i]) tarjin(i); 63 for (int i = 1 ; i <= n ; i++) { 64 for (int j = head[i] ; ~j; j = edge[j].next ) { 65 if (belong[edge[j].v] != belong[i]) du[belong[i]]++; 66 } 67 } 68 int ansrt, zero = 0; 69 for (int i = 1 ; i <= cnt ; i++) { 70 if (!du[i]) { 71 ansrt = i; 72 zero++; 73 } 74 } 75 if (zero == 1) { 76 int ans = 0; 77 for (int i = 1 ; i <= n ; i++) { 78 if (belong[i] == ansrt) ans++; 79 } 80 printf("%d\n", ans); 81 } else printf("0\n"); 82 } 83 return 0; 84 }

poj 2186 強連通入門題目