您的位置:首页 > 其它

POJ2553 The Bottom of a Graph 强连通 tarjan

2011-10-30 19:28 483 查看
题意:此题最难的部分即是理解题意。

注意要求得点的定义为:所有这个点能到达的点都能到达这个点。

思路:

强连通,缩点,找出出度为0的强连通分量集合,就是要求得点集合。

#include<iostream>
#define min(a,b) (a<b?a:b)
using namespace std;
const int N=5005;
bool mat

;
int dfn
,low
;
bool instack
;
int indgr
;
int outdgr
;
int stack
;
int sp;
int index;
int n,m;
int belong
;
void tarjan(int i)
{
dfn[i]=low[i]=index++;
stack[sp++]=i;
instack[i]=true;
for(int j=1;j<=n;j++)
{
if(mat[i][j])
{
if(!dfn[j])
{
tarjan(j);
low[i]=min(low[i],low[j]);
}
else if(instack[j])
{
low[i]=min(dfn[j],low[i]);
}
}
}
if(low[i]==dfn[i])
{
int j;
do
{
j=stack[--sp];
instack[j]=false;
belong[j]=i;
}while(j!=i);
}
}
void solve()
{
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(mat[i][j])
{
if(belong[i]!=belong[j])
{
indgr[belong[j]]++;
outdgr[belong[i]]++;
}
}
}
for(int i=1;i<=n;i++)
{
if(outdgr[belong[i]]==0)
{
printf("%d ",i);
}
}
printf("\n");
}
int main()
{
while(scanf("%d%d",&n,&m),n!=0)
{
index=1;
sp=1;
memset(indgr,0,sizeof(indgr));
memset(outdgr,0,sizeof(outdgr));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(mat,0,sizeof(mat));
memset(instack,0,sizeof(instack));
memset(stack,0,sizeof(stack));
memset(belong,0,sizeof(belong));
int from,to;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&from,&to);
mat[from][to]=true;
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: