POJ 2186 Popular Cows(Tarjan)

http://poj.org/problem?id=2186

题意 :给你n头牛,m对关系,每对关系由两个编号组成,u和v代表着u认为v是受欢迎的,如果1认为2是受欢迎的,2认为3是受欢迎的,那1认为3也是受欢迎的。

思路 :强联通分量的Tarjan做法,将这些牛之间的关系看成一个有向图,最受欢迎的那个牛的那个点一定是出度为0的点。Tarjan的基本资料:http://hi.baidu.com/lydrainbowcat/item/1c664b662b1a1692c4d2491c

#include <stdio.h>

#include <stack>

#include <string.h>

#include <stdlib.h>

#include <algorithm>

#include <iostream>



using namespace std;



const int maxn = 10002 ;

const int maxm = 50002 ;

stack<int >Q ;

int head[maxn],ID[maxn],low[maxn],dfn[maxn],in[maxn],out[maxn] ;

int cnt,cntt,n,m ,ans;



struct node

{

    int v,next,id ;

}Edge[maxm] ;



void addedge(int u,int v,int w)

{

    Edge[w].v = v ;

    Edge[w].next = head[u] ;

    head[u] = w ;

}



void tarjan(int u)

{

    int v,t ;

    int minn = dfn[u] = low[u] = cnt++ ;

    Q.push(u) ;

    for(int k = head[u] ; k+1 ; k = Edge[k].next)

    {

        v = Edge[k].v ;

        if(dfn[v] == -1)

        tarjan(v) ;

        minn = min(minn,low[v]) ;

    }

    if(minn < low[u]) {low[u] = minn ; return ;}

    do

    {

        ID[t = Q.top()] = cntt ;

        low[t] = n ;

        out[cntt]++ ;

        Q.pop() ;

    }while(t != u) ;

    cntt++ ;

}



void Init()

{

    memset(head,-1,sizeof(head)) ;

    memset(dfn,-1,sizeof(dfn)) ;

    memset(in,0,sizeof(in)) ;

    memset(out,0,sizeof(out)) ;

    cnt = cntt = ans = 0 ;

}

int main()

{

    while(~scanf("%d %d",&n,&m))

    {

        Init() ;

        int u,v ,flag;

        for(int i = 0 ; i < m ; i++)

        {

            scanf("%d %d",&u,&v) ;

            addedge(u-1,v-1,i) ;

        }

        for(int i = 0 ; i < n ; i++)

        if(dfn[i] == -1)

        tarjan(i) ;

        for(int i = 0 ; i < n ; i++)

        {

            for(int j = head[i] ; j+1 ; j = Edge[j].next)

            {

                int a = ID[i],b = ID[Edge[j].v] ;

                if(a != b) in[ID[i]]++ ;

            }

        }

        for(int i = 0 ; i < cntt ; i++)

        {

            if(!in[i])

            {

                ans++ ;

                flag = i ;

            }

        }

        if(ans == 1) printf("%d\n",out[flag]) ;

        else printf("0\n") ;

    }

    return 0;

}
View Code

 

你可能感兴趣的:(tar)