[HAOI2006]受欢迎的牛

来源:互联网 发布:淘宝商城手机专卖店 编辑:程序博客网 时间:2024/06/06 03:16

Luogu P2341

做这道题的时候,出了一个蠢蠢的错误,主程序只写了一行 tarjan(1),而当 1->2<-3 时,结点 3 是不能被遍历到的。

被所有奶牛喜欢的奶牛,即所有点都可以到达的结点。显然是新图中出度为 0 的缩点。而当含有多个这样的缩点时,这些缩点之间是不能互相到达的,这时候答案为 0。

在有向图中,如果有且仅有一个点的出度为0 (没有指向其他点的边),那么该点可以被所有点遍历到;反之,该图中没有可以被所有点遍历到的点

在有向图中,如果一个点可以被所有点遍历到,那么这个点的出度为0

#include<cstdio>#include<algorithm>using namespace std;const int N = 10005;struct edge{    int from,to,next;}e[5*N];struct edge2{    int to,next;}g[5*N];int head[N],low[N],dfn[N],color[N],col_num,num[N],f[N],head2[N],tot2,dfs_clock,sta[N],top,oudgr[N];bool isin[N];void tarjan(int u){    low[u]=dfn[u]=++dfs_clock;    isin[u]=true;    sta[++top]=u;    for(int i=head[u];i;i=e[i].next)    {        int v=e[i].to;        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(isin[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(low[u]==dfn[u])    {        isin[u]=false;        color[u]=++col_num;        while(sta[top]!=u)        {            int v=sta[top];            color[v]=col_num;            isin[v]=false;            ++num[col_num];            --top;        }        ++num[col_num];        --top;    }}int main(){    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;++i)    {        int u,v;        scanf("%d%d",&u,&v);        e[i].next = head[u];        e[i].from = u;        e[i].to = v;        head[u] = i;    }    for(int i=1;i<=n;++i)    {        if(!dfn[i])        {            dfs_clock=0;            tarjan(i);        }    }    for(int i=1;i<=m;++i)    {        int u=e[i].from,v=e[i].to;        if(color[u]!=color[v])        {            ++oudgr[color[u]];        }    }    bool flag=false;    int ans=0;    for(int i=1;i<=col_num;++i)    {        if(oudgr[i]==0)        {            if(flag)            {                ans=0;                break;            }            ans=num[i];            flag=true;        }    }    printf("%d\n",ans);    return 0;}
原创粉丝点击