[poj 2186]Popular Cows[Tarjan强连通分量]

2014-11-23 20:10:32 · 作者: · 浏览: 6

题意:

有一群牛, a会认为b很帅, 且这种认为是传递的. 问有多少头牛被其他所有牛认为很帅~

思路:

关键就是分析出缩点之后的有向树只能有一个叶子节点(出度为0).

做法就是Tarjan之后缩点统计出度.


#include 
#include 
#include 
#include 
using namespace std;
const int MAXN = 10005;
const int MAXE = 50005;
struct pool
{
    int v,pre;
}p[MAXE];
int num,head[MAXN];
int dfn[MAXN],low[MAXN],id[MAXN],dag[MAXN];
bool vis[MAXN];
int size,Index,n,m;
stack s;
void add(int u, int v)
{
    p[++num].v = v;
    p[num].pre = head[u];
    head[u] = num;
}

void Tarjan(int u)
{
    low[u] = dfn[u] = ++Index;
    vis[u] = true;
    s.push(u);
    for(int tmp = head[u],k;k = p[tmp].v,tmp;tmp = p[tmp].pre)
    {
        if(!dfn[k])
        {
            Tarjan(k);
            low[u] = min(low[u],low[k]);
        }
        else if(vis[k])
            low[u] = min(low[u],low[k]);
    }
    if(dfn[u]==low[u])
    {
        size++;
        int k;
        do
        {
            k = s.top();s.pop();
            vis[k] = false;
            id[k] = size;
        }while(k!=u);
    }
}

void shrink()
{
    for(int i=1;i<=n;i++)
        for(int tmp = head[i],k;k = p[tmp].v,tmp;tmp = p[tmp].pre)
            if(id[i]!=id[k])
                dag[id[i]]++;//缩点
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0,u,v;i