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

 

posted on 2014-02-17 13:29  枫、  阅读(217)  评论(0编辑  收藏  举报