Poj 3180 The Cow Prom
http://poj.org/problem?id=3180
题意:一群牛被有向的绳子拴起来,如果有一些牛(>=2)的绳子是同向的,他们就能跳跃。求能够跳跃的组数。
题解:求元素大于等于2的强连通分量的数量。
1 // 2 // main.cpp 3 // Poj 3180 4 // 5 // Created by zhang on 14-4-10. 6 // Copyright (c) 2014年 apple. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <cstring> 11 #include <cstdio> 12 #include <cstdlib> 13 #include <cmath> 14 #include <string> 15 #include <vector> 16 #include <list> 17 #include <map> 18 #include <queue> 19 #include <stack> 20 #include <bitset> 21 #include <algorithm> 22 #include <numeric> 23 #include <functional> 24 #include <set> 25 #include <fstream> 26 27 using namespace std; 28 29 const int maxn=50010; 30 31 int V; 32 vector<int> G[maxn]; 33 vector<int> rG[maxn]; 34 vector<int> vs; 35 bool used[maxn]; 36 int cmp[maxn]; 37 int A[maxn],B[maxn]; 38 int N,M; 39 int num,setnum[maxn],belong[maxn]; 40 int cnt1,cnt2; 41 42 void add_edge(int from,int to) 43 { 44 G[from].push_back(to); 45 rG[to].push_back(from); 46 } 47 48 void dfs(int v) 49 { 50 used[v]=true; 51 for (int i=0; i<G[v].size(); i++) { 52 if (!used[G[v][i]]) { 53 dfs(G[v][i]); 54 } 55 } 56 vs.push_back(v); 57 } 58 59 void rdfs(int v,int k) 60 { 61 used[v]=true; 62 cmp[v]=k; 63 num++; 64 for (int i=0; i<rG[v].size(); i++) { 65 if (!used[rG[v][i]]) { 66 rdfs(rG[v][i], k); 67 } 68 } 69 } 70 71 int scc() 72 { 73 memset(used, 0, sizeof(used)); 74 vs.clear(); 75 for (int v=0; v<V; v++) { 76 if (!used[v]) { 77 dfs(v); 78 } 79 } 80 memset(used, 0, sizeof(used)); 81 int k=0; 82 for (int i=vs.size()-1; i>=0; i--) { 83 if (!used[vs[i]]) { 84 num=0; 85 rdfs(vs[i], k++); 86 setnum[cnt2++]=num; 87 } 88 } 89 return k; 90 } 91 92 int main() 93 { 94 //freopen("/Users/apple/Desktop/题/Poj 3180/Poj 3180/in", "r", stdin); 95 //freopen("/Users/apple/Desktop/题/Poj 3180/Poj 3180/out", "w", stdout); 96 while((scanf("%d%d",&N,&M))!=EOF){ 97 V=N; 98 for (int i=0; i<M; i++) { 99 scanf("%d%d",&A[i],&B[i]); 100 add_edge(A[i]-1, B[i]-1); 101 } 102 cnt1=cnt2=1; 103 int n=scc(); 104 int res=0; 105 for (int i=0; i<cnt2; i++) { 106 if (setnum[i]>=2) { 107 res++; 108 } 109 } 110 printf("%d\n",res); 111 } 112 return 0; 113 }