tarjan condensing point applications Popular Cows POJ - 2186

Simple applications, this problem because all the big data requirements violence, certainly not, the point is to shrink to become a part of the point, which is part of the point is the same, this is to this figure those points into a strongly connected, because a strong a little over-worship each other connected components, all of them can shrink point. Then after that point reduction if a point has to worship other points then it will not be its point of worship worship (or it will shrink to a point), it is required that did not go to other people's point of worship. If there is one, then this is the large number of small points which point, if there are two or more it shows there is no link two points, all is not all worship.

#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<stack>

using namespace std;

const int maxn = 1e4 + 10;
struct node
{
    int next, to;
};

node edge[500010];
int dfn[maxn], low[maxn], color[maxn], vis[maxn], du[maxn], head[maxn], cnt[maxn];
int tot, deep, num;
stack<int>Q;
void add(int u, int to)
{
    edge[tot] = (node){head[u], to};
    head[u] = tot++;
}
void tarjan(int x)
{
    vis[x] = 1;
    dfn[x] = ++deep;
    low[x] = dfn[x];
    Q.push(x);
    for(int i = head[x]; ~i; i = edge[i].next)
    {
        int to = edge[i].to;
        if(!dfn[to])
        {
            tarjan(to);
            low[x] = min(low[x], low[to]);
        }
        else
        {
            if(vis[to])
            {
                low[x] = min(low[x], low[to]); // dfn[to]
            }
        }
    }
    if(dfn[x] == low[x])
    {
        color[x] = ++num;
        vis[x] = 0; // 别漏了
        while(Q.top() != x)
        {
            color[Q.top()] = num;
            vis[Q.top()] = 0;
            Q.pop();
        }
        Q.pop();
    }
}

int main()
{
    int n, m;
    tot = 0;
    memset(head, -1, sizeof(head));
    num = 0, deep = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i < m; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
        //du[u]++;
    }
    for(int i = 1; i <= n; i++)
    {
        if(!dfn[i])
        {
            tarjan(i);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = head[i]; ~j; j = edge[j].next)
        {
            int to = edge[j].to;
            if(color[i] != color[to])
            {
                du[color[i]]++;
            }
        }
        cnt[color[i]]++;
    }
    int tmp = 0, ans = 0;
    for(int i = 1; i <= num; i++)
    {
        if(du[i] == 0)
        {
            tmp++;
            ans = cnt[i];
        }
    }
    if(tmp == 0)
        printf("0\n");
    else
    {
        if(tmp > 1)
            printf("0\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}

Published 40 original articles · won praise 13 · views 848

Guess you like

Origin blog.csdn.net/weixin_43891021/article/details/102783657