标签:
| 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