标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 23445 | Accepted: 9605 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Source
”
#include <stdio.h> #include <string.h> #define maxn 10002 #define maxm 50002 int head0[maxn], head1[maxn], id; int count[maxn], num[maxn], hash[maxn]; struct Node{ int t0, next0, t1, next1; } E[maxm]; bool vis[maxn], out[maxn]; void addEdge(int u, int v) { E[id].t0 = v; E[id].next0 = head0[u]; head0[u] = id; E[id].t1 = u; E[id].next1 = head1[v]; head1[v] = id++; } void getMap(int n, int m) { int i, u, v; id = 0; memset(head0, -1, sizeof(int) * (n + 1)); //save time memset(head1, -1, sizeof(int) * (n + 1)); for(i = 0; i < m; ++i){ scanf("%d%d", &u, &v); addEdge(u, v); } } void DFS0(int pos, int& sig) { vis[pos] = 1; int i; for(i = head0[pos]; i != -1; i = E[i].next0){ if(!vis[E[i].t0]) DFS0(E[i].t0, sig); } num[++sig] = pos; } void DFS1(int pos, int sig) { vis[pos] = 1; hash[pos] = sig; int i; ++count[sig]; for(i = head1[pos]; i != -1; i = E[i].next1){ if(!vis[E[i].t1]) DFS1(E[i].t1, sig); else if(hash[E[i].t1] != hash[pos]) out[hash[E[i].t1]] = 1; } } void solve(int n) //Kosaraju { int i, sig = 0, tmp = 0, ans; memset(vis, 0, sizeof(bool) * (n + 1)); for(i = 1; i <= n; ++i) if(!vis[i]) DFS0(i, sig); memset(vis, 0, sizeof(bool) * (n + 1)); memset(count, 0, sizeof(int) * (n + 1)); memset(out, 0, sizeof(bool) * (n + 1)); i = sig; sig = 0; for(; i; --i) if(!vis[num[i]]) DFS1(num[i], ++sig); for(i = 1; i <= sig; ++i) if(!out[i]) ++tmp, ans = count[i]; //printf("sig%d\n", sig); if(tmp == 1) printf("%d\n", ans); else printf("0\n"); } int main() { int n, m; while(scanf("%d%d", &n, &m) == 2){ getMap(n, m); solve(n); } return 0; }
#include <stdio.h> #include <string.h> #define maxn 10002 #define maxm 50002 int head[maxn], vis[maxn], id, id2, scc_num, sec; int dfn[maxn], low[maxn], sta[maxn], count[maxn]; bool out[maxn]; struct Node{ int to, next; } E[maxm]; int min(int a, int b){ return a < b ?a : b; } void addEdge(int u, int v) { E[id].to = v; E[id].next = head[u]; head[u] = id++; } void getMap(int n, int m) { int i, u, v; id = 0; memset(head, -1, sizeof(int) * (n + 1)); memset(vis, 0, sizeof(int) * (n + 1)); memset(out, 0, sizeof(bool) * (n + 1)); memset(count, 0, sizeof(int) * (n + 1)); for(i = 0; i < m; ++i){ scanf("%d%d", &u, &v); addEdge(u, v); } } void DFS(int pos) //强连通分量必然是该树的子树 { dfn[pos] = low[pos] = ++sec; vis[pos] = 1; sta[id2++] = pos; int i, u, v; for(i = head[pos]; i != -1; i = E[i].next){ v = E[i].to; if(!vis[v]) DFS(v); if(vis[v] == 1) low[pos] = min(low[pos], low[v]); } if(dfn[pos] == low[pos]){ ++scc_num; do{ ++count[scc_num]; u = sta[--id2]; low[u] = scc_num; vis[u] = 2; } while(u != pos); } } void solve(int n) //Tarjan { int i, j, ok = 0, ans; sec = id2 = scc_num = 0; for(i = 1; i <= n; ++i) if(!vis[i]) DFS(i); for(i = 1; i <= n; ++i) for(j = head[i]; j != -1; j = E[j].next) if(low[i] != low[E[j].to]){ out[low[i]] = 1; break; } for(i = 1; i <= scc_num; ++i) if(!out[i]){ if(++ok > 1) break; ans = count[i]; } if(ok != 1) printf("0\n"); else printf("%d\n", ans); } int main() { int n, m; while(scanf("%d%d", &n, &m) == 2){ getMap(n, m); solve(n); } return 0; }
#include <stdio.h> #include <string.h> #define maxn 10002 #define maxm 50002 //sta2用以维护当前连通分量的根 int head[maxn], id, sta1[maxn], id1, sta2[maxn], id2; int low[maxn], scc[maxn], sccNum, sec, count[maxn]; struct Node{ int to, next; } E[maxm]; bool out[maxn]; void addEdge(int u, int v) { E[id].to = v; E[id].next = head[u]; head[u] = id++; } void getMap(int n, int m) { int i, u, v; id = 0; memset(head, -1, sizeof(int) * (n + 1)); for(i = 0; i < m; ++i){ scanf("%d%d", &u, &v); addEdge(u, v); } } void Garbow(int pos) { low[pos] = ++sec; sta1[id1++] = sta2[id2++] = pos; for(int i = head[pos]; i != -1; i = E[i].next){ if(!low[E[i].to]) Garbow(E[i].to); else if(!scc[E[i].to]){ while(low[sta2[id2-1]] > low[E[i].to]) --id2; } } if(pos == sta2[id2-1]){ int v; ++sccNum; --id2; do{ v = sta1[--id1]; scc[v] = sccNum; ++count[sccNum]; } while(sta1[id1] != pos); } } void solve(int n) { int i, j; id1 = id2 = sec = sccNum = 0; memset(low, 0, sizeof(int) * (n + 1)); memset(scc, 0, sizeof(int) * (n + 1)); memset(count, 0, sizeof(int) * (n + 1)); memset(out, 0, sizeof(bool) * (n + 1)); for(i = 1; i <= n; ++i) if(!low[i]) Garbow(i); for(i = 1; i <= n; ++i) for(j = head[i]; j != -1; j = E[j].next) if(scc[i] != scc[E[j].to]){ out[scc[i]] = 1; break; } int tmp = 0, ans; for(i = 1; i <= sccNum; ++i) if(!out[i]){ if(++tmp > 1){ ans = 0; break; } ans = count[i]; } printf("%d\n", ans); } int main() { int n, m; while(scanf("%d%d", &n, &m) == 2){ getMap(n, m); solve(n); } return 0; }
POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】
标签:
原文地址:http://www.cnblogs.com/yxwkf/p/5218415.html