poj2553--Tarjan算法
题目大意:
此题主要难点在于题目的理解:A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from v, v is also reachable from w.
sink 就是指某个能到达的点也能到达他自己的,即他们在同一个强联通分量中。
题目解法:找到出度为0的强联通分量中的所有点都是符合要求的。题目还要求将最终答案排序后输出,这里wa了一次,我以为是每个强联通分量单独排序。
题目源码:
//#define LOCAL
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define MAXN 5500
#define INF 0x3f3f3f3f
int n, m;
struct Edge
{
int to;
int next;
};
Edge edge[MAXN * MAXN];
int head[MAXN], e;
int dfn[MAXN], low[MAXN], cnt;
int stack[MAXN], top;
int instack[MAXN];
int belong[MAXN], index;
int out[MAXN];
int ans[MAXN];
int min(int a, int b)
{
return a < b ? a : b;
}
void addEdge(int u, int v)
{
edge[e].to = v;
edge[e].next = head[u];
head[u] = e++;
}
void init()
{
int i, j;
int u, v;
e = 0;
cnt = 1;
top = 0;
index = 0;
memset(head, -1, sizeof(head));
memset(dfn, -1, sizeof(dfn));
memset(low, -1, sizeof(low));
memset(instack, 0, sizeof(instack));
memset(belong, 0, sizeof(belong));
memset(out, 0, sizeof(out));
memset(ans, 0, sizeof(ans));
for(i = 1; i <= m; i++)
{
scanf("%d%d", &u, &v);
addEdge(u, v);
}
}
void tarjan(int u)
{
int i, v;
low[u] = dfn[u] = cnt++;
instack[u] = 1;
stack[++top] = u;
for(i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if(dfn[v] == -1)
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(instack[v])
low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u])
{
index++;
do
{
v = stack[top--];
belong[v] = index;
}
while(top != 0 && v != u);
}
}
void solve()
{
int i, j;
int v;
int flag;
while(scanf("%d%d", &n, &m) && n)
{
flag = 1;
init(); // 获得head数组及edge数组
for(i = 1; i <= n; i++)
if(dfn[i] == -1)
tarjan(i); // 获得belong数组
for(i = 1; i <= n; i++)
{
for(j = head[i]; j != -1; j = edge[j].next) // 获得out数组
{
v = edge[j].to;
if(belong[i] != belong[v])
out[belong[i]]++;
}
}
flag = 1;
for(i = 1; i <= n; i++)
{
if(!out[belong[i]])
{
if(flag)
{
printf("%d", i);
flag = 0;
}
else
{
printf(" %d", i);
}
}
}
printf("\n");
}
}
int main()
{
#ifdef LOCAL
freopen("poj2553.txt", "r", stdin);
freopen("poj2553Out.txt", "w", stdout);
#endif
solve();
return 0;
}