poj 2186 Popular Cows
强连通分量 tarjan
http://poj.org/problem?id=2186
#include <iostream>
#include "stdio.h"
#include "string.h"
using namespace std;
struct node
{
int v, next;
}edge[50000];
const int MAXV = 10001;
int adj[MAXV], lp, low[MAXV], dfn[MAXV], out[MAXV], belong[MAXV], stack[MAXV], index, top, num;
bool instack[MAXV];
void addedge(int u, int v)
{
edge[lp].v = v;
edge[lp].next = adj[u];
adj[u] = lp++;
}
void tarjan(int u)
{
low[u] = dfn[u] = ++index;
stack[++top] = u;
instack[u] = true;
for(int i = adj[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(instack[v])
low[u] = min(low[u], dfn[v]);
}
int tmp;
if(low[u] == dfn[u])
{
num++;
do
{
tmp = stack[top--];
instack[tmp] = false;
belong[tmp] = num;
}while(tmp != u);
}
}
int main()
{
int nv, ne, i, j, a, b;
while(scanf("%d%d", &nv, &ne) != EOF)
{
num = top = index = lp = 0;
memset(adj, -1, sizeof(adj));
memset(dfn, 0, sizeof(dfn));
memset(out, 0, sizeof(out));
memset(instack, false, sizeof(instack));
for(i = 0; i < ne; i++)
{
scanf("%d%d", &a, &b);
addedge(a, b);
}
for(i = 1; i <= nv; i++)
if(!dfn[i]) tarjan(i);
for(i = 1; i <= nv; i++)
for(j = adj[i]; j != -1; j = edge[j].next)
if(belong[i] != belong[edge[j].v]) out[belong[i]]++;
int ans = 0, cnt = 0, pos;
for(i = 1; i <= num; i++)
if(out[i] == 0)
{
cnt++; //记录出度为0的强连通分量的个数
pos = i;
}
if(cnt == 1)
{
for(i = 1; i <= nv; i++)
if(belong[i] == pos) ans++;
}
cout << ans << endl;
}
return 0;
}