POJ 2186 Popular Cows

Popular Cows
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 21685   Accepted: 8852

Descriptionios

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. 

Inputide

* 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. 

Outputthis

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

Sample Inputspa

3 3
1 2
2 1
2 3

Sample Outputcode

1

Hintorm

Cow 3 is the only cow of high popularity. 

Sourceblog

 

初学强连通份量第一题排序

假设有两头牛A和B都被其余全部牛认为是红人,那么显然A、B也互相认为是红人,即存在一个包含A、B两个顶点的圈,即A和B同属于同一个强连通份量。由此咱们可知,若是一头牛被其它全部牛认为是红人,那么它所在的强连通份量内的全部牛都被其余全部牛认为是红人。这样咱们把图进行强连通分解后,至多有一个强连通份量知足题目的条件。ip

咱们知道,把一个图进行强连通份量分解后,能够获得各个强连通份量拓扑排序后的顺序,而在此题中,惟一可能成为解的只有拓扑序最后的一个强连通份量。所以咱们在对图进行强连通份量分解后,只要检查最后一个强连通份量中的一个顶点是否从全部顶点到达就行了。ci

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<vector>
  4 #include<cstring>
  5 #define MAX_V 10050
  6 
  7 using namespace std;
  8 
  9 int V,E;
 10 vector<int> G[MAX_V];
 11 vector<int> rG[MAX_V];
 12 vector<int> vs;
 13 bool used[MAX_V];
 14 int cmp[MAX_V];
 15 
 16 void add_edge(int _from,int _to)
 17 {
 18     G[_from].push_back(_to);
 19     rG[_to].push_back(_from);
 20 }
 21 
 22 void dfs(int v)
 23 {
 24     used[v]=true;
 25     for(int i=0;i<G[v].size();i++)
 26         if(!used[G[v][i]])
 27             dfs(G[v][i]);
 28     vs.push_back(v);
 29 }
 30 
 31 void rdfs(int v,int k)
 32 {
 33     used[v]=true;
 34     cmp[v]=k;
 35     for(int i=0;i<rG[v].size();i++)
 36         if(!used[rG[v][i]])
 37             rdfs(rG[v][i],k);
 38 }
 39 
 40 int scc()
 41 {
 42     memset(used,false,sizeof(used));
 43     vs.clear();
 44     for(int v=0;v<V;v++)
 45         if(!used[v])
 46             dfs(v);
 47 
 48     memset(used,false,sizeof(used));
 49     int k=0;
 50     for(int i=vs.size()-1;i>=0;i--)
 51         if(!used[vs[i]])
 52         {
 53             rdfs(vs[i],k);
 54             k++;
 55         }
 56 
 57     return k;
 58 }
 59 
 60 int main()
 61 {
 62     while(scanf("%d %d",&V,&E)==2)
 63     {
 64         for(int i=0;i<V;i++)
 65         {
 66             G[i].clear();
 67             rG[i].clear();
 68         }
 69 
 70         int a,b;
 71         for(int i=1;i<=E;i++)
 72         {
 73             scanf("%d %d",&a,&b);
 74             add_edge(a-1,b-1);
 75         }
 76 
 77         int k=scc()-1;
 78         int u,ans=0;
 79 
 80         for(int i=0;i<V;i++)
 81             if(cmp[i]==k)
 82             {
 83                 u=i;
 84                 ans++;
 85             }
 86 
 87         //再反向图上再进行一次DFS,判断最后一个强连通份量中的点是不是从全部点均可达的
 88         memset(used,false,sizeof(used));
 89         if(ans)
 90         {
 91             rdfs(u,0);
 92             for(int i=0;i<V;i++)
 93                 if(!used[i])
 94                 {
 95                     ans=0;
 96                     break;
 97                 }
 98         }
 99 
100         printf("%d\n",ans);
101     }
102 
103     return 0;
104 }
[C++]
相关文章
相关标签/搜索