码迷,mamicode.com
首页 > 移动开发 > 详细

POJ 2186 Popular Cows (强联通分量)

时间:2015-05-21 14:14:19      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

链接 :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;
}


 

POJ 2186 Popular Cows (强联通分量)

标签:

原文地址:http://blog.csdn.net/u013923947/article/details/45890789

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!