POJ 2186 Popular Cows (Tarjan)

题目描述:

  有n只牛,牛之间存在一些关系,比如a认为b很受欢迎,b认为c很受欢迎,这样呢,a也会认为c很受欢迎,问根据给出的关系,有多少头牛被其他所有的牛都认为是受欢迎的?

解题思路:

  对于一个有向无环图来说,其中有且仅有一个点出度为零,那么这个特殊的点,可以由其他任何点到达。那么接下来我们直接对所给的图进行强连通分量划分,然后把每个强连通分量看做一个点,判定出度为零的点有几个,如果有一个就输出这个点对应的强连通分量含有的节点个数,否则为零。

#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>

using namespace std;

const int maxn=1e4+10;

struct node{
    int to,nxt;
}edge[maxn*5];

int head[maxn],tot;
int low[maxn],dfn[maxn],sta[maxn],belg[maxn],out[maxn];
int index,top;
int scc;
bool instack[maxn];

void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].nxt=head[u];
    head[u]=tot++;
}

void Tarjan(int u){
    int v;
    low[u]=dfn[u]=++index;
    sta[top++]=u;
    instack[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        v=edge[i].to;
        if(!dfn[v]){
            Tarjan(v);
        }
        if(instack[v]){
            low[u]=min(low[u],low[v]);
        }
    }
    if(low[u]==dfn[u]){
        scc++;
        do{
            v=sta[--top];
            instack[v]=0;
            belg[v]=scc;
        }while(v!=u);
    }
}

void init(){
    tot=index=scc=top=0;
    memset(dfn,0,sizeof dfn);
    memset(instack,0,sizeof instack);
    memset(low,0,sizeof low);
    memset(head,-1,sizeof head);
    memset(out,0,sizeof out);
}

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        while(m--){
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]){
                Tarjan(i);
            }
        }
        int sum=0,x;
        for(int i=1;i<=n;i++){
            for(int j=head[i];~j;j=edge[j].nxt){
                if(belg[i]!=belg[edge[j].to]){
                    out[belg[i]]++;
                }
            }
        }
        for(int i=1;i<=scc;i++){
            if(!out[i]){
                sum++;
                x=i;
            }
        }
        if(sum==1){
            sum=0;
            for(int i=1;i<=n;i++){
                if(belg[i]==x){
                    sum++;
                }
            }
            printf("%d\n",sum);
        }else printf("0\n");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/84390875
今日推荐