标签:
Time Limit: 2000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Source
由于popular可以传递,所以可以把奶牛之间的关系看做一个有向图。为了处理方便,把这个图中的每个强连通分量看做一个整体(缩点)。
缩点之后的图是一个有向无环图(必然无环,因为如果有环,环可以继续缩)
在这个新图里找出度为0的点,如果出度为0的点只有一个,那么这个点对应的强连通分量里所有的奶牛都满足题意,如果出度为0的点有多个,那么无解(想一想为什么)
tarjan算法解如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<vector> 6 #include<cstring> 7 using namespace std; 8 const int mxn=12000; 9 int n,m; 10 vector <int> e[mxn]; 11 int dfn[mxn],low[mxn]; 12 int st[mxn],top; 13 bool inst[mxn]; 14 int vis[mxn]; 15 int dtime=0; 16 int cnt=0; 17 int belone[mxn],num[mxn]; 18 int out[mxn]; 19 void tarjan(int u){ 20 int v,i; 21 dfn[u]=++dtime; 22 low[u]=dtime; 23 inst[u]=true; 24 st[++top]=u; 25 for(i=0;i<e[u].size();i++){ 26 v=e[u][i]; 27 if(dfn[v]==-1){ 28 tarjan(v); 29 low[u]=min(low[u],low[v]); 30 } 31 else if(inst[v]){ 32 low[u]=min(low[u],dfn[v]); 33 } 34 } 35 if(dfn[u]==low[u]){ 36 cnt++; 37 do{ 38 i=st[top--]; 39 inst[i]=false; 40 belone[i]=cnt; 41 num[cnt]++; 42 }while(i!=u); 43 } 44 // printf("test cnt:%d\n",cnt); 45 return; 46 } 47 void solve(){ 48 int i,j; 49 for(i=1;i<=n;i++){ 50 for(j=0;j<e[i].size();j++){ 51 // printf("test: u:%d v:%d belone[v]:%d\n",i,e[i][j],belone[e[i][j]]); 52 if(belone[i]!=belone[e[i][j]])out[belone[i]]++;//计算出度 53 } 54 } 55 int flag=0,mark; 56 for(i=1;i<=cnt;i++){ 57 if(out[i]==0)flag++,mark=i; 58 } 59 if(flag==1){ 60 printf("%d\n",num[mark]); 61 } 62 else printf("0\n"); 63 return; 64 } 65 int main(){ 66 scanf("%d%d",&n,&m); 67 int u,v; 68 int i,j; 69 for(i=1;i<=m;i++){ 70 scanf("%d%d",&u,&v); 71 e[u].push_back(v); 72 } 73 memset(dfn,-1,sizeof(dfn));//dfn初始化 74 for(i=1;i<=n;i++){ 75 if(dfn[i]==-1)tarjan(i); 76 } 77 solve(); 78 return 0; 79 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5574961.html