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++]
相關文章
相關標籤/搜索