1. 程式人生 > >BZOJ 1051 [HAOI2006]受歡迎的牛

BZOJ 1051 [HAOI2006]受歡迎的牛

技術分享 lose string dfs typedef ++ none include urn

tarjan縮點,之後出度為0的點的size就是答案,若有多個出度為0的點則答案為0;

技術分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
typedef long long LL;
const int maxn=50000+299;
using namespace std;
int n,m,u,v,dfs_clock,dfn[maxn],low[maxn],num[maxn],tot;
int fir[maxn],nxt[maxn],to[maxn],ecnt,out[maxn],e[maxn][2],sz[maxn]; void add(int u,int v) { nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; } stack<int>sta; void tarjan(int x) { dfn[x]=low[x]=++dfs_clock; sta.push(x); for(int i=fir[x];i;i=nxt[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[x]
=min(low[x],low[to[i]]); } else if(!num[to[i]]) low[x]=min(low[x],dfn[to[i]]); } if(dfn[x]==low[x]) { ++tot; for(;;) { int u=sta.top(); sta.pop() ; num[u]=tot; sz[tot]++; if(u==x) break; } } }
int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); e[i][0]=u; e[i][1]=v; add(u,v); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=m;i++) { u=num[e[i][0]]; v=num[e[i][1]]; if(u!=v) out[u]++; } int flag=0,ans=0; for(int i=1;i<=tot;i++) { if(!flag&&!out[i]) { ans=sz[i]; flag=1; } else if(flag&&!out[i]) { flag=0; break; } } if(!flag) ans=0; printf("%d\n",ans); return 0; }
View Code

BZOJ 1051 [HAOI2006]受歡迎的牛