bzoj1051 受欢迎的牛
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
tarjan+缩点,最后答案为出度为0的sum,如果有多个出度为0的点,那么答案为0.
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e4+10,maxm=5e4+10; int n,m; bool cd[maxn]; int aa,ff;char cc; int read() { aa=0;cc=getchar();ff=1; while(cc<'0'||cc>'9') { if(cc=='-') ff=-1; cc=getchar(); } while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa*ff; } int fir[maxn],nxt[maxm],to[maxm],e=0; void add(int x,int y) { to[++e]=y;nxt[e]=fir[x];fir[x]=e; } int zz[maxn],id[maxn],top[maxn],d=0,t=0; bool vis[maxn],inz[maxn]; int xd[maxn],sum[maxn],tot; void tj(int pos) { id[pos]=top[pos]=++d; vis[pos]=inz[pos]=1; zz[++t]=pos; int z; for(int y=fir[pos];y;y=nxt[y]) { z=to[y]; if(vis[z]) { if(inz[z]) top[pos]=min(top[pos],top[z]); continue; } tj(z); top[pos]=min(top[pos],top[z]); } if(top[pos]==id[pos]) { sum[++tot]=0; while(t) { xd[zz[t]]=tot; inz[zz[t]]=0; sum[tot]++; t--; if(zz[t+1]==pos) break; } } } int main() { n=read();m=read(); int x,y,ans=0; for(int i=1;i<=m;++i) { x=read();y=read(); add(x,y); } tj(1); for(int i=1;i<=n;++i) for(int y=fir[i];y;y=nxt[y]) { if(xd[to[y]]!=xd[i]) cd[xd[i]]=1; } for(int i=1;i<=tot;++i) if(!cd[i]){ if(ans) { ans=0; break; } ans=sum[i]; } printf("%d",ans); return 0; }
弱者就是会被欺负呀