Tarjin算法

来源:互联网 发布:mac os 10.13 iso下载 编辑:程序博客网 时间:2024/05/19 21:00

Tarjin算法一种用于寻找强连通图的算法。

每当搜索到一个点时,就将其入栈,用dfn[]数组记录搜索到该点的时间,用low[]数组记录该点所在的强连通图所在搜索子树的根节点的dfn值

具体操作:

1、首次搜索到某个点时,将其dfn与low值初始化,定义为发现此点时的时间,并将其入栈

2、当发现一个点与其相连时,判断此点是否在栈内,若在,则原点的low值等于其与被发现点dfn值的最小值;若不在,对此点进行Tarjin,则原点的low值等于其与被发现点low值的最小值

3、在以上操作结束之后,若发现此点的dfn与low值相等,则此点为其所在强连通图所在搜索子树的根结点,而栈中此点以及其栈上方的点在同一个强连通图中

4、对不在此强连通图中的点继续进行搜索

如图:从1出发,进行DFS一直到6结束,结点6为一个强连通图,后返回至4->1->2->1->3->5,5结束,结点5为强连通图,返回3->1,结点1的dfn与low值相等,1,2,3,4在同一个强连通图中。

附代码如下:

#include<stdio.h>bool f[10001][10001]={0};int n,tarjin1[10001]={0},ifstack[10001]={0},tarjin2=0,stack[10001]={0},top=0,low[10001]={0},dfn[10001]={0},begintime=0,end[10001]={0},endtime=0;void push(int x){top++;stack[top]=x;return ;}int min(int x,int y){if(x>y)return y;return x;}void tarjin(int p){int i;low[p]=dfn[p]=++begintime;push(p);ifstack[p]=1;for(i=1;i<=n;i++){if(f[p][i]&&ifstack[i]!=-1){if(ifstack[i]){low[p]=min(low[p],dfn[i]);}else{tarjin(i);low[p]=min(low[p],low[i]);}}}if(low[p]==dfn[p]){while(stack[top+1]!=p){printf("%d ",stack[top]);ifstack[stack[top]]=-1;top--;}printf("\n",stack[top]);}end[p]=++endtime;return ;}int main(){int m,i;scanf("%d%d",&n,&m);for(i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);f[x][y]=true;}tarjin(1);/*for(i=1;i<=n;i++){printf("%d:%d %d\n",i,dfn[i],end[i]);}*/return 0;}


0 0