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 }

 


 

posted @ 2014-04-26 10:57  Der_Z  阅读(259)  评论(0编辑  收藏  举报