1. 程式人生 > >bzoj1051: [HAOI2006]受歡迎的牛

bzoj1051: [HAOI2006]受歡迎的牛

esp oid tchar 喜歡 www return void code top

題目傳送門 又是一波復習題.....

tarjan縮點後圖就不存在環了 尋找每個環的出度 如果一個環被所有點間接或者直接指向並且這個環沒有出度那麽答案就是這個環上點的個數(當然也只能存在一個環)

如果存在兩個點沒有出度 那麽就不存在被所有牛喜歡的牛 答案就是0了

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=50007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<
0||c>9){if(c==-) f=-1; c=getchar();} while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();} return ans*f; } int n,m,sum,first[M]; int color[M],out[M],s[M],num,ans,last; int dfn[M],low[M],cnt,st[M],top,book[M]; struct node{int to,next;}e[M]; void insert(int a,int b){sum++; e[sum].to=b; e[sum].next=first[a]; first[a]=.sum;}
void dfs(int x){ dfn[x]=low[x]=++cnt; book[x]=1; st[++top]=x; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!dfn[now]){ dfs(now); low[x]=min(low[x],low[now]); } if(book[now]) low[x]=min(low[x],dfn[now]); } if(low[x]==dfn[x]){ s[
++num]=1; book[x]=0; color[x]=num; while(st[top]!=x){ int now=st[top--]; book[now]=0; color[now]=num; s[num]++; } top--; } } int main() { int x,y; n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y); for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i); for(int i=1;i<=n;i++) for(int j=first[i];j;j=e[j].next) if(color[e[j].to]!=color[i]){ out[color[i]]=1; break; } for(int i=1;i<=num;i++) if(!out[i]){ if(last){ printf("0\n"); return 0; } last=i; } printf("%d\n",s[last]); return 0; }
View Code

bzoj1051: [HAOI2006]受歡迎的牛