BZOJ(3) 1051: [HAOI2006]受歡迎的牛
阿新 • • 發佈:2018-06-03
algo 模板 sum clu bzoj back -s iostream --
Submit: 7365 Solved: 3937
[Submit][Status][Discuss]
能出現多個A,B)
1 2
2 1
2 3
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是受歡迎的(給出的信息有可能重復,即有可Output
一個數,即有多少頭牛被所有的牛認為是受歡迎的。
Sample Input
3 31 2
2 1
2 3
Sample Output
1HINT
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]); }
BZOJ(3) 1051: [HAOI2006]受歡迎的牛