[HAOI2006]受欢迎的牛

来源:互联网 发布:推荐系统算法模型 编辑:程序博客网 时间:2024/05/16 13:54

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶
牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜
欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你
算出有多少头奶牛可以当明星。

这道题。。只有一个字。。水…

不过有一个性质,在DAG上如果有且只有一个点没有出度,那么所有点都可以到达它。

#include<bits/stdc++.h>using namespace std;const int MAXN=1e5+5;struct edge{    int to,next;}e[MAXN<<1];int n,m;int head[MAXN],cnt=0;inline void add(int u,int v){e[++cnt]=(edge){v,head[u]},head[u]=cnt;}int dfn[MAXN],low[MAXN],sta[MAXN],belong[MAXN],out[MAXN],stanum=0,times=0,num=0;bool insta[MAXN];void tarjan(int u){    dfn[u]=low[u]=++times;    sta[++stanum]=u;    insta[u]=1;    for(int i=head[u];i;i=e[i].next){        int v=e[i].to;        if(!dfn[v]){            tarjan(v);            if(low[v]<low[u])low[u]=low[v];        }        else if(insta[v]&&dfn[v]<low[u])low[u]=dfn[v];    }    if(dfn[u]==low[u]){        int tem=0;++num;        while(tem!=u){            tem=sta[stanum--];            belong[tem]=num;            insta[tem]=0;        }    }}int main(){    int tem1,tem2;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        scanf("%d%d",&tem1,&tem2);        add(tem1,tem2);    }    for(int i=1;i<=n;i++){        if(!dfn[i])tarjan(i);    }    for(int u=1;u<=n;u++){        for(int i=head[u];i;i=e[i].next){            int v=e[i].to;            if(belong[v]!=belong[u])out[belong[u]]++;        }       }    int flag=0,ans=0;    for(int i=1;i<=num;i++){        if(!out[i]){            flag++;            tem1=i;         }    }    if(flag>1){        printf("0\n");return 0;    }    for(int i=1;i<=n;i++){        if(belong[i]==tem1)ans++;    }    printf("%d\n",ans);    return 0;}