Descriptionhtml
Inputios
Outputgit
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 }