Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
3 3
1 2
2 1
2 3
1 2
2 1
2 3
Sample Output
1
tarjan缩点之后统计出度为0的点的大小,有多个就直接输出0
#include<cstdio> #define N 10010 #define M 50010 struct edge{ int to,next; }e[M]; int n,m; int head[N]; int pre[N],low[N]; int sccnum[N],have[N]; int cnt,cnt2,cnt3,top; int zhan[3*N]; int p[N]; inline int min(int a,int b) {return a<b?a:b;} inline void ins(int u,int v) { e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } inline void rebuild() { for (int i=1;i<=n;i++) for (int j=head[i];j;j=e[j].next) if (sccnum[i]!=sccnum[e[j].to]) p[sccnum[i]]++; } inline void dfs(int x) { zhan[++top]=x; low[x]=pre[x]=++cnt2; for (int i=head[x];i;i=e[i].next) { if(!pre[e[i].to]) { dfs(e[i].to); low[x]=min(low[x],low[e[i].to]); }else if(!sccnum[e[i].to]) low[x]=min(low[x],pre[e[i].to]); } if (pre[x]==low[x]) { cnt3++; int p=-1; while (p!=x) { p=zhan[top]; top--; sccnum[p]=cnt3; have[cnt3]++; } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); ins(x,y); } for (int i=1;i<=n;i++) if (!pre[i]) dfs(i); rebuild(); int tot=0,sav; for (int i=1;i<=cnt3;i++) if (!p[i])tot++,sav=i; if (tot>1) { printf("0\n"); return 0; }else printf("%d",have[sav]); }
——by zhber,转载请注明来源