標籤:
連結 :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 (強聯通分量)