bzoj1051 [HAOI2006]受欢迎的牛

来源:互联网 发布:有多少网络交易平台 编辑:程序博客网 时间:2024/06/07 00:28

题目

哇,CSDN博客皮肤改版了,还有什么优质博主抢先体验版,手贱点了试用,哇塞,好。。。。。。丑。不过据说全部都要改,这样我的心情就好了许多。

再来看这道题,比较经典的tarjan缩点题。
先用tarjan缩点,点内每一个小点都能互相到达。大点之间建有向边,如果只存在一个大点的出度为0,那么它的大小就是答案。存在多个的话,答案为0。

#include<bits/stdc++.h>#define N 50000using namespace std;int m,n,x[N+1],y[N+1];int first[N+1],nex[N+1],to[N+1],siz; int dfn[N+1],low[N+1],cnt,sta[N+1],top,id;int belong[N+1],num[N+1];int cd[N+1],ans,rd[N+1],tot;bool vis[N+1];inline char nc(){    static char buf[100000],*p1=buf,*p2=buf;    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int read(){    int x=0,b=1;    char c=nc();    for(;!(c<='9'&&c>='0');c=nc())if(c=='-')b=-1;    for(;c<='9'&&c>='0';c=nc())x=x*10+c-'0';    return x*b;}inline void write(int x){    if(x==0)putchar('0');    else    {        char buf[15];        int len=0;        if(x<0)putchar('-'),x=-x;        while(x)buf[++len]=x%10+'0',x/=10;        for(int i=len;i>=1;i--)putchar(buf[i]);    }//  putchar(' ');}inline void add(int x,int y){    nex[siz]=first[x];    first[x]=siz;    to[siz]=y;    siz++;}inline void dfs(int x){    dfn[x]=low[x]=++id;    sta[++top]=x,vis[x]=true;    for(int i=first[x];i!=-1;i=nex[i])    {        int u=to[i];        if(!dfn[u])            dfs(u),low[x]=min(low[x],low[u]);                else if(vis[u])low[x]=min(low[x],dfn[u]);    }    if(low[x]==dfn[x])    {        cnt++;int tmp;        do        {            tmp=sta[top--];            vis[tmp]=false;            belong[tmp]=cnt;            num[cnt]++;        }while(tmp!=x);    }}int main(){    freopen("in.txt","r",stdin);    n=read(),m=read();    memset(first,-1,sizeof(first));    for(int i=1;i<=m;i++)        x[i]=read(),y[i]=read(),add(x[i],y[i]);    cnt=id=0;    for(int i=1;i<=n;i++)if(!dfn[i])dfs(i);    siz=0,memset(first,-1,sizeof(first));    for(int i=1;i<=m;i++)        if(belong[x[i]]!=belong[y[i]])add(belong[x[i]],belong[y[i]]),cd[belong[x[i]]]++,rd[belong[y[i]]]++;    for(int i=1;i<=cnt;i++)        if(cd[i]==0)ans+=num[i],tot++;     if(tot==1)write(ans);    else write(0);    return 0;}