POJ 2186 POPULAR COWS

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

注意题中 是 considered popular by every other cow 意思是除了他自己其他牛都喜欢他的

我一开始理解为 the most popular =-= 

利用tarjan算出强连通分支 缩点 得出出度为0的个数num(num一定不会等于0的)

如果num为1 则为该强连通图的牛个数

否则 没有这样的牛

NOTE: 题中说明是稀疏图  最好用邻接表

View Code
#include <cstdio>
#include <iostream>
#include <stack>
using std::stack;

const int maxn = 10005, INF = (1<<30);
bool vis[maxn], inStack[maxn];
int dfn[maxn], low[maxn], belong[maxn], size[maxn], m, n, round, cnt;
int out[maxn];
struct node
{
    int index;
    node *next;
}edge[maxn];
stack<int> s;
int min(int a, int b)
{
    return a<=b ?a :b ;
}
void tarjan(int u)
{
    int i;
    dfn[u] = low[u] = round ++ ;
    vis[u] = 1;
    inStack[u] = 1;
    s.push(u);
    node *p = edge[u].next;
    while( p != NULL )
    {
        int v = p->index;
        if( !vis[v] )
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if( inStack[v] )
            low[u] = min(low[u], dfn[v]);
        p = p->next;
    }
    if( low[u] == dfn[u] )
    {
        cnt ++;
        while(i = s.top())
        {
            size[cnt] ++;
            belong[i] = cnt;
            inStack[i] = 0;
            s.pop();
            if( i==u )
                break;
        }
    }
}
void init()
{
    cnt = 0, round = 1;
}
int check()
{
    for(int i=1; i<=n; i++)
        if( !vis[i] )
            return i;
    return 0;
}
int main()
{
    int i, a, b;
    scanf("%d %d", &n, &m);
    init();
    for(i=1; i<=m; i++)
    {
        scanf("%d %d", &a, &b);
        if( a == b )
            continue;
        node *p = (node *)malloc(sizeof(node));
        p->index = b;
        p->next = edge[a].next;
        edge[a].next = p;
    }
    while( i=check() )
        tarjan(i);
    for(i=1; i<=n; i++)
    {
        node *p = edge[i].next;
        while( p != NULL )
        {
            if( belong[i] != belong[p->index])
                out[belong[i]]++ ;
            p = p->next;
        }
    }
    int minNum = INF, ans = 0;
    for(i=1; i<=cnt; i++)
    {
        if(out[i] == 0)
        {
            if(minNum != INF)
            {   minNum = 0; break; }
            minNum = size[i] ;
        }
    }
    printf("%d\n", minNum);
    return 0;
}

 

posted @ 2013-02-27 14:42  April_Tsui  阅读(135)  评论(0编辑  收藏  举报