Popular Cows (POJ No.2186)

Descriptionhtml

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. 

Inputios

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

Outputgit

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

Sample Inputide

3 3
1 2
2 1
2 3

Sample Outputthis

1



題解:
考慮以牛爲頂點的有向圖,對每一個需對(A,B)連一條從A到B的邊。咱們不妨假設兩頭牛A,B都被其餘牛認爲是紅牛。那麼就知道A,B必定同屬一個強連通份量,即存在一個包含A,B兩個頂點的圈。反之,若是一個牛被其餘牛認爲是紅牛,那麼他所屬的強連通份量中的牛必定所有是紅牛。因此咱們只須要找出拓撲序最大的強連通份量的個數就能夠了。

AC代碼:
 1 #include<iostream>
 2 #include<cctype>
 3 using namespace std;
 4 const int MAXN=500000+10;
 5 //-------------------------
 6 void read(int &x){
 7     x=0;char ch=getchar();int f=1;
 8     for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
 9     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
10     x*=f;
11 }
12 //-------------------------
13 int n,m,tmp;
14 int topo[MAXN],cmp[MAXN];
15 bool vis[MAXN];
16 int first[MAXN],next[MAXN],v[MAXN],e;
17 void AddEdge(int a,int b){
18     v[++e]=b;
19     next[e]=first[a];
20     first[a]=e;
21 }
22 
23 int rfirst[MAXN],rnext[MAXN],rv[MAXN],re;
24 void rAddEdge(int a,int b){
25     rv[++re]=b;
26     rnext[re]=rfirst[a];
27     rfirst[a]=re;
28 }
29 //-------------------------
30 void dfs(int x){
31     vis[x]=1;
32     for(int i=first[x];i;i=next[i])
33         if(!vis[v[i]])dfs(v[i]);
34     topo[++tmp]=x;
35 }
36 
37 void rdfs(int x,int k){
38     vis[x]=1;
39     cmp[x]=k;
40     for(int i=rfirst[x];i;i=rnext[i])
41         if(!vis[rv[i]])rdfs(rv[i],k);
42 }
43 //---------------------------
44 int k=1;
45 int scc(){
46     memset(vis,0,sizeof(vis));
47     memset(topo,0,sizeof(topo));
48     for(int i=1;i<=n;i++){
49         if(!vis[i])dfs(i);
50     }
51     memset(vis,0,sizeof(vis));
52     for(int i=n;i>=1;i--)if(!vis[topo[i]])rdfs(topo[i],k++);
53     return k-1;
54 }
55 //---------------------------
56 int main(){
57     read(n);read(m);
58     for(int i=1;i<=m;i++){
59         int x,y;
60         read(x);read(y);
61         AddEdge(x,y);
62         rAddEdge(y,x);
63     }
64     int nn=scc();
65     
66     int u=0,num=0;
67     for(int i=1;i<=n;i++)
68         if(cmp[i]==nn){u=i;num++;}
69     memset(vis,0,sizeof(vis));
70     rdfs(u,0);
71     for(int i=1;i<=n;i++)
72         if(!vis[i]){
73             num=0;
74             break;
75         }
76     printf("%d\n",num);
77 } 
View Code
相關文章
相關標籤/搜索