标签:有一个 说明 缩点 algo 任务 else 就是 printf time
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N(1<=N<=10000)头牛,给你M(1<=M<=50000)对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。
第一行输入n,m
下面m行每行输入x,y表示x到y有一条边
输出受欢迎奶牛的数量
3 3 1 2 2 1 2 3
1
先tarjan缩点,对于新建的图中,出度为0的点如果只有一个,说明这个点(缩过)被所有奶牛欢迎。否则的话就不可能有
奶牛被所有的牛认为是受欢迎。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<algorithm> 6 struct nd1 7 { 8 int next,to; 9 } e1[150005]; 10 int head[110005],out[110005],sc,cnt; 11 inline void insert(int u,int v) 12 { 13 e1[++cnt].next=head[u]; 14 head[u]=cnt; 15 e1[cnt].to=v; 16 } 17 int time,s[110005],vis[110005],dfn[110005],low[110005],bl[110005],num[110005]; 18 int n,m; 19 inline void tarjan(int now) 20 { 21 dfn[now]=low[now]=++time; 22 s[++s[0]]=now;vis[now]=1; 23 for(int i=head[now];i;i=e1[i].next) 24 { 25 if(!dfn[e1[i].to]) 26 { 27 tarjan(e1[i].to); 28 low[now]=std::min(low[now],low[e1[i].to]); 29 } 30 else if(vis[e1[i].to]) 31 low[now]=std::min(low[now],dfn[e1[i].to]); 32 } 33 if(dfn[now]==low[now]) 34 { 35 num[bl[now]=++sc]=1; 36 vis[now]=0; 37 while(s[s[0]]!=now) 38 { 39 vis[s[s[0]]]=0; 40 bl[s[s[0]]]=sc; 41 num[sc]++; 42 s[0]--; 43 } 44 s[0]--; 45 } 46 } 47 inline void rdeg() 48 { 49 for(int i=1;i<=n;i++) 50 for(int j=head[i];j;j=e1[j].next) 51 { 52 if(bl[i]!=bl[e1[j].to]) 53 out[bl[i]]++; 54 } 55 } 56 int main() 57 { 58 int u,v; 59 scanf("%d%d",&n,&m); 60 for(int i=1;i<=m;i++) 61 { 62 scanf("%d%d",&u,&v); 63 insert(u,v); 64 } 65 for(int i=1;i<=n;i++) 66 if(!dfn[i]) tarjan(i); 67 rdeg(); 68 int ans=0; 69 for(int i=1;i<=sc;i++) 70 { 71 if(!out[i] && !ans) ans=num[i]; 72 else if(!out[i] && ans!=0) 73 { 74 ans=-1; 75 break; 76 } 77 } 78 if(ans==-1) puts("0\n"); 79 else printf("%d\n",ans); 80 return 0; 81 }
标签:有一个 说明 缩点 algo 任务 else 就是 printf time
原文地址:http://www.cnblogs.com/Dndlns/p/7857617.html