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 }
 
  

 

 
 

 

转载于:https://www.cnblogs.com/der-z/p/3690971.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值