POJ2186 Popular Cows

Description

Every cow‘s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is 
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

* Line 1: Two space-separated integers, N and M

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

Output

* Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity.

Source

USACO 2003 Fall

正解:tarjan+缩环成点

解题报告:

  有一周(4天)没写题了,马上期末考试了,一直在搞学科,但是还是想刷道题保持手感。。。考完期末就可以搞一个暑假竞赛了

  题目大意是给定一个有向图,找到所有点都能到达的点的个数。

  一眼秒题,tarjan算法,然后缩环,发现只有一个出边为0的环,则环中所有点都是合法解;如果不止一个,那么无解。

  POJ上交了一发,一遍AC,手感还不错。

  1 //It is made by jump~
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <ctime>
  9 #include <vector>
 10 #include <queue>
 11 #include <map>
 12 #ifdef WIN32
 13 #define OT "%I64d"
 14 #else
 15 #define OT "%lld"
 16 #endif
 17 using namespace std;
 18 typedef long long LL;
 19 const int MAXN = 10011;
 20 const int MAXM = 50011;
 21 int n,m;
 22 int ecnt,cnt,total;
 23 int first[MAXN],next[MAXM],to[MAXM];
 24 int belong[MAXN];
 25 int dfn[MAXN],low[MAXN];
 26 bool pd[MAXN];
 27 int Stack[MAXN],top;
 28 int out[MAXN];
 29 int ans,jilu;
 30
 31 inline int getint()
 32 {
 33        int w=0,q=0;
 34        char c=getchar();
 35        while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar();
 36        if (c==‘-‘)  q=1, c=getchar();
 37        while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar();
 38        return q ? -w : w;
 39 }
 40
 41 inline void Init(){
 42     ecnt=0; cnt=0; total=0; top=0;
 43     memset(first,0,sizeof(first));
 44     memset(pd,0,sizeof(pd));
 45     memset(dfn,0,sizeof(dfn));
 46     memset(Stack,0,sizeof(Stack));
 47 }
 48
 49 inline void link(int x,int y){
 50     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
 51 }
 52
 53 inline void dfs(int x){
 54     dfn[x]=++total; low[x]=dfn[x];
 55     pd[x]=1;
 56     Stack[++top]=x;
 57     for(int i=first[x];i;i=next[i]) {
 58     int v=to[i];
 59     if(!dfn[v]) {
 60         dfs(v);
 61         low[x]=min(low[x],low[v]);
 62     }
 63     else if(pd[v] && low[v]<low[x]) low[x]=low[v];
 64     }
 65     if(dfn[x]==low[x]) {
 66     cnt++;
 67     int now=Stack[top];
 68     do{
 69         belong[now]=cnt;
 70         pd[now]=0; top--;
 71         if(now==x) break;
 72         now=Stack[top];
 73     }while(1);
 74     }
 75 }
 76
 77 inline void tarjan(){
 78     for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
 79 }
 80
 81 inline void solve(){
 82     while(scanf("%d%d",&n,&m)!=EOF) {
 83     Init();
 84     int x,y;
 85     for(int i=1;i<=m;i++) {
 86         x=getint(); y=getint();
 87         link(x,y);
 88     }
 89     tarjan();
 90     for(int i=1;i<=n;i++){
 91         for(int j=first[i];j;j=next[j]) {
 92         int v=to[j];
 93         if(belong[v]!=belong[i]) {
 94             out[belong[i]]++;
 95         }
 96         }
 97     }
 98     ans=0,jilu=0;
 99     for(int i=1;i<=cnt;i++){
100         if(out[i]==0) {
101         ans++; jilu=i;
102         }
103     }
104     if(ans==1) {
105         ans=0;
106         for(int i=1;i<=n;i++) {
107         if(belong[i]==jilu) ans++;
108         }
109         printf("%d\n",ans);
110     }
111     else printf("0\n");
112     }
113 }
114
115 int main()
116 {
117   solve();
118   return 0;
119 }
时间: 2024-10-23 08:02:55

POJ2186 Popular Cows的相关文章

poj2186 Popular Cows --- 强连通

给一个有向图,问有多少结点是其他所有结点都可以到达的. 等价于,在一个有向无环图上,找出度为0 的结点,如果出度为0的结点只有一个,那么这个就是答案,如果大于1个,则答案是0. 这题有环,所以先缩点.求唯一出度为0的强连通分量. #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<iostream> #define inf 0x3f3f3f3f

强连通分量tarjan缩点——POJ2186 Popular Cows

这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定意味着v可达u.    相互可达则属于同一个强连通分量    (Strongly Connected Component, SCC) §有向图和它的转置的强连通分量相同 §所有SCC构成一个DAG(有向无环图) dfn[u]为节点u搜索的次序编号(时间戳),即首次访问u的时间 low[u]为u或u的

POJ2186 Popular Cows 【强连通分量Kosaraju】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &l

POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &l

POJ2186 Popular Cows【Kosaraju】【强连通分量】

Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24266Accepted: 9954 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 5

POJ2186 Popular Cows [tarjan 缩点]

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31241   Accepted: 12691 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &

poj2186 Popular Cows 题解——S.B.S.

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29642   Accepted: 11996 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &

POJ2186 Popular Cows ,有向图, Tarjan算法

题意: 给定一个有向图,求有多少个顶点是由任何顶点出发都可达的. 顶点数<= 10,000,边数 <= 50,000 定理: 有向无环图中唯一出度为0的点,一定可以由任何点出发均可达 (由于无环,所以从任何点出发往前走,必然终止于一个出度为0的点) 1. 求出所有强连通分量 2. 每个强连通分量缩成一点,则形成一个有向无环图DAG. 3. DAG上面如果有唯一的出度为0的点,则该点能被所有的点可达.那么该点所代表的连通分量上的所有的原图中的点,都能被原图中的所有点可达,则该连通分量的点数,就是

[POJ2186]Popular Cows(强连通分量)

题目链接:http://poj.org/problem?id=2186 给定n个点m条边,求某点使得其他点都有通向它的一条路径,计算这个点集的大小. 强连通分解后求出度为0的连通分量的个数,如果有且仅有一个连通分量出度为1,则统计这个连通分量中点的数目. 遍历所有点的出边指向的点,判断这两个点是否属于同一个连通分量,记录每个连通分量中的点的数目. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip&