【bzoj1051】【HAOI2006】受歡迎的牛
阿新 • • 發佈:2018-09-20
getch getchar while fir getc cout emp con 關系
題目描述
每頭奶牛都夢想成為牛棚裏的明星。被所有奶牛喜歡的奶牛就是一頭明星奶牛。所有奶牛都是自戀狂,每頭奶牛總是喜歡自己的。奶牛之間的“喜歡”是可以傳遞的——如果A喜歡B,B喜歡C,那麽A也喜歡C。牛欄裏共有N 頭奶牛,給定一些奶牛之間的愛慕關系,請你算出有多少頭奶牛可以當明星。
輸入
第一行:兩個用空格分開的整數:N和M
第二行到第M + 1行:每行兩個用空格分開的整數:A和B,表示A喜歡B
輸出
第一行:單獨一個整數,表示明星奶牛的數量
樣例輸入
3 3 1 2 2 1 2 3
樣例輸出
1
題解
tarjan縮點模版。
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=10000+50; const int maxm=50000+50; int fir[maxn],to[maxm],nex[maxm],ecnt,deep,sum; int n,m,x,y,col[maxn],du[maxn],cnt[maxn],stack[maxn],low[maxn],dfn[maxn],t,tmp;bool vis[maxn]; void add_edge(int u,int v){ nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v; } template<typename T>void read(T& aa){ char cc; ll ff;aa=0;cc=getchar();ff=1; while((cc<‘0‘||cc>‘9‘)&&cc!=‘-‘) cc=getchar(); if(cc==‘-‘) ff=-1,cc=getchar(); while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar(); aa*=ff; } int tarjan(int u){ dfn[u]=++deep; low[u]=deep; vis[u]=1; stack[++t]=u; for(int e=fir[u];e;e=nex[e]){ int v=to[e]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else{ if(vis[v]) low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ col[u]=++sum; vis[u]=0; while(stack[t]!=u){ col[stack[t]]=sum; vis[stack[t--]]=0; } t--; } } int main(){ read(n),read(m); for(int i=1;i<=m;i++){ read(x),read(y); add_edge(x,y); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++){ for(int e=fir[i];e;e=nex[e]){ int v=to[e]; if(col[i]!=col[v]) du[col[i]]++; } cnt[col[i]]++; } for(int i=1;i<=sum;i++) if(du[i]==0){ tmp++;x=i; } if(tmp==0) cout<<0<<endl; else if(tmp>1) cout<<0<<endl; else cout<<cnt[x]<<endl; return 0; }
【bzoj1051】【HAOI2006】受歡迎的牛