您的位置:首页 > 其它

Tarjan 算法自我总结

2016-07-18 19:17 281 查看
 首先要说一下,强连通分量是指有向图里顶点间能互相到达的子图,并不一定要各点之间连在一起。 极大强连通图 是一个没有被其他连通图完全包含的图。

所以说Tarjan算法是来求强连通图的。

tarjan算法 代码如下:

void tar(int a)

{

 int i,b;

 dfn[a]=low[a]=++t; put(a);

 for(i=v[a].fir;i!=0;i=arcnum[i].next)

 {

 b=arcnum[i].go;

 if(dfn[b]==0)

 {

   tar(b);

   low[a]=min(low[a],low[b]);

    }

  else if(vis[b])

  low[a]=min(dfn[b],low[a]);

   }

   if(low[a]==dfn[a])

   {

    do

    {

       b=push();

       f[b]=k;

    }while(a!=b);

    k++;

   }

}

附上:POJ2186 代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=10000+100;
struct node{int data,fir;}v[maxn];
struct arcc{int go,next;}arcnum[70000];
int sum,top,stack[maxn];
void addarc(int a,int b)
{
sum++;
arcnum[sum].go=b;
arcnum[sum].next=v[a].fir;
v[a].fir=sum;
}
int low[maxn],dfn[maxn],t,vis[maxn],f[maxn],k=1,flag[maxn];
void put(int a)
{vis[a]=1; stack[++top]=a;}
int push()
{vis[stack[top]]=0; return stack[top--];}
void tar(int a)
{
int i,b;
dfn[a]=low[a]=++t; put(a);
for(i=v[a].fir;i!=0;i=arcnum[i].next)
{
b=arcnum[i].go;
if(dfn[b]==0)
{
tar(b);
low[a]=min(low[a],low[b]);
}
else if(vis[b])
low[a]=min(dfn[b],low[a]);
}
if(low[a]==dfn[a])
{
do
{
b=push();
f[b]=k;
}while(a!=b);
k++;
}
}
int outgdr[maxn];
int main()
{
int n,m,i,j,a,b,jl;
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d %d",&a,&b);
addarc(a,b);
}
for(i=1;i<=n;i++)
if(!dfn[i])
tar(i);
for(i=1;i<=n;i++)
for(j=v[i].fir;j!=0;j=arcnum[j].next)
{
a=f[i]; b=f[arcnum[j].go];
if(a!=b)
outgdr[a]++;
}

a=0; b=0;
for(i=1;i<k;i++)
if(outgdr[i]==0)
a++,jl=i;
for(i=1;i<=n;i++)
if(f[i]==jl)
b++;
if(a==1)
printf("%d",b);
else if(b==n)
printf("%d",n);
else
printf("0");
/*for(i=1;i<=n;i++)
printf(" %d %d\n",i,f[i]);*/
return 0;
}
值得注意的一点,int main()里面空间不足够多,如果开大一点儿的数组开在int main() 外才能开出来,否则数据大了,什么都输不出来,而且还会报错。

缩点: 是指把一个强连通图看成一个点,具体操作是,在tarjan里面,进行一部分修改,强连通分量里有写,就把
4000
它看成一个点,运用时候,加if语句判断即可。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: