LOJ #10091. 「一本通 3.5 例 1」受歡迎的牛
阿新 • • 發佈:2018-11-10
題目描述
原題來自:USACO 2003 Fall
每一頭牛的願望就是變成一頭最受歡迎的牛。現在有 NNN 頭牛,給你 MMM 對整數 (A,B)(A,B)(A,B),表示牛 AAA 認為牛 BBB 受歡迎。這種關係是具有傳遞性的,如果 AAA 認為 BBB 受歡迎,BBB 認為 CCC 受歡迎,那麼牛 AAA 也認為牛 CCC 受歡迎。你的任務是求出有多少頭牛被除自己之外的所有牛認為是受歡迎的。
輸入格式
第一行兩個數 N,MN,MN,M;
接下來 MMM 行,每行兩個數 A,BA,BA,B,意思是 AAA 認為 BBB 是受歡迎的(給出的資訊有可能重複,即有可能出現多個 A,BA,BA,B)。
輸出格式
輸出被除自己之外的所有牛認為是受歡迎的牛的數量。
樣例
樣例輸入
3 3
1 2
2 1
2 3
樣例輸出
1
樣例說明
只有第三頭牛被除自己之外的所有牛認為是受歡迎的。
資料範圍與提示
對於全部資料,1≤N≤104,1≤M≤5×1041\le N\le 10^4,1\le M\le 5\times 10^41≤N≤104,1≤M≤5×104。
當這是一棵樹的時候,很容易看出求每個點的出度,輸出是否存在出度為0的點
(如果有多個結點,是不可能有奶牛被其餘牛都歡迎,答案為0)
但這是一個有向圖,所以要縮點後進行如上的操作
#include<cstdio> #include<iostream> using namespace std; int read() { int ret=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') ret=(ret<<1)+(ret<<3)+ch-'0',ch=getchar(); return ret; } const int N=1e6+4; int n,m,a[N],d[N],ans; int he[N],to[N],nxt[N],cnt; int dfn[N],sgn,low[N],st[N],top,co[N],col; struct NA{ int u,v; }e[N]; inline void add(int u,int v) { to[++cnt]=v; nxt[cnt]=he[u]; he[u]=cnt; } void Tarjan(int u) { dfn[u]=low[u]=++sgn; st[++top]=u; for(int e=he[u];e;e=nxt[e]) { int v=to[e]; if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]); else if(!co[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { co[u]=++col; while(top&&st[top]!=u) co[st[top--]]=col; top--; } } int main() { n=read(),m=read(); for(int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(), add(e[i].u,e[i].v); for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); for(int i=1;i<=n;i++) a[co[i]]++; for(int i=1;i<=m;i++) if(co[e[i].v]!=co[e[i].u]) d[co[e[i].u]]++; for(int i=1;i<=col;i++) if(!d[i]) { if(!ans) ans=a[i]; else { ans=0; break; } } printf("%d\n",ans); }