POJ 2186 Popular Cows (强联通分量)

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

一个联通分量里的所有的牛满足任何一个被其他牛认为是红人。强联通缩点之后 只需要找到一个且只有一个联通分量且它的出度为0 答案就是这个强联通分量点的个数。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <map>
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mem(a) memset(a,0,sizeof(a))
typedef long long ll;
const int N = 10005;
const int M = 50005;
const ll mod = 1000000007;

using namespace std;

int n, m, dfs_clock, scc_cnt;
int he[N], pre[N], low[N], scc[N];
stack <int> S;

struct C {
    int ne, to;
} e[M];

void add(int id, int x, int y) {
    e[id].to = y;
    e[id].ne = he[x];
    he[x] = id;
}

void dfs(int u) {

    pre[u] = low[u] = ++ dfs_clock;
    S.push(u);
    for(int i = he[u]; i != -1; i = e[i].ne) {

        int v = e[i].to;
        if(pre[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if(scc[v] == 0) {
            low[u] = min(low[u], pre[v]);
        }

    }

    if(low[u] == pre[u]) {
        scc_cnt ++;
        while(1) {
            int x = S.top(); S.pop();
            scc[x] = scc_cnt;
            if(x == u) break;
        }
    }

}

void find_scc() {
    mem(scc);
    mem(pre);
    dfs_clock = scc_cnt = 0;
    for(int i = 1; i <= n; i++) {
        if(pre[i] == 0) dfs(i);
    }
}

int out[N], v[N];

int main() {

    while(cin >> n >> m) {
        memset(he, -1, sizeof(he));
        for(int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            add(i, x, y);
        }

        find_scc();

        mem(v);
        for(int i = 1; i <= n; i++) {
            v[ scc[i] ]++;
        }
        //printf("%d\n", scc_cnt);
        int ans;
        for(int u = 1; u <= n; u++) {
            for(int i = he[u]; i != -1; i = e[i].ne) {
                int v = e[i].to;
                if(scc[u] != scc[v]) {
                    out[scc[u]] = 1;
                }
            }
        }

        int cnt = 0;
        for(int i = 1; i <= scc_cnt; i++) {
            if(out[i] == 0) {
                cnt++;
                ans = v[i];
            }
        }

        if(cnt == 1) {
            printf("%d\n", ans);
        } else puts("0");

    }

    return 0;
}


 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。