BZOJ(3) 1051: [HAOI2006]受欢迎的牛
1051: [HAOI2006]受欢迎的牛
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7365 Solved: 3937
[Submit][Status][Discuss]
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
HINT
100%的数据N<=10000,M<=50000
思路:tarjin模板。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 50010 using namespace std; int n,m,tim,tot,top,sumcol; int col[MAXN],sum[MAXN],num[MAXN]; int to[MAXN],net[MAXN],from[MAXN],head[MAXN]; int vis[MAXN],low[MAXN],dfn[MAXN],strack[MAXN],visstrack[MAXN]; void add(int u,int v){ to[++tot]=v;from[tot]=u;net[tot]=head[u];head[u]=tot; } void tarjin(int now){ strack[++top]=now; low[now]=dfn[now]=++tim; vis[now]=1;visstrack[now]=1; for(int i=head[now];i;i=net[i]) if(visstrack[to[i]]) low[now]=min(low[now],dfn[to[i]]); else if(!vis[to[i]]){ tarjin(to[i]); low[now]=min(low[now],low[to[i]]); } if(low[now]==dfn[now]){ sumcol++;sum[sumcol]++; col[now]=sumcol; while(strack[top]!=now){ col[strack[top]]=sumcol; visstrack[strack[top]]=0; top--;sum[sumcol]++; } visstrack[now]=0; top--; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); } for(int i=1;i<=n;i++) if(!vis[i]) tarjin(i); for(int i=1;i<=tot;i++) if(col[from[i]]!=col[to[i]]) num[col[from[i]]]++; int flag=0,ans; for(int i=1;i<=sumcol;i++) if(num[i]==0){ flag++; ans=i; } if(flag!=1) printf("0\n"); else printf("%d\n",sum[ans]); }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。