一直想写的关于tarjan算法的理解——向struct edge大佬低头
tarjan的算法精髓就是dfn[]和low[]数组
dfn[i]表示在该节点被搜索的次序(时间戳)
low[i]表示i或i的子树可以追溯到的最早的栈中节点
判断有强连通分量的条件就是
dfn[i]==low[i] 此时就可以判断i或i的子树是一个强联通分量
那么tarjan的算法过程是什么呢?
大致如下:
从某一个节点开始,如果该节点还未入栈,那么它的dfn[i]=i;low[i]=i;
如果已经入栈了,那么它的low[i]就是当前该节点入栈时dfn[i]的值,而不是现在i的值。
如果想要更加准确的理解tarjan,那么我推荐一篇大佬的博客
链接如下,里面清晰的解释了tarjan的算法原理,我就是通过这个大佬的博客学会的tarjan (代码也是copy的这位大佬的)
http://www.cnblogs.com/shadowland/p/5872257.html
博客名字叫:
Tarjan 算法&模板
来自:
struct Edge大佬的博客
下面是代码:
void Tarjan ( int x ) { dfn[ x ] = ++dfs_num ; low[ x ] = dfs_num ; vis [ x ] = true ;//是否在栈中 stack [ ++top ] = x ; for ( int i=head[ x ] ; i!=0 ; i=e[i].next ){ int temp = e[ i ].to ; if ( !dfn[ temp ] ){ Tarjan ( temp ) ; low[ x ] = gmin ( low[ x ] , low[ temp ] ) ; } else if ( vis[ temp ])low[ x ] = gmin ( low[ x ] , dfn[ temp ] ) ; } if ( dfn[ x ]==low[ x ] ) {//构成强连通分量 vis[ x ] = false ; color[ x ] = ++col_num ;//染色 while ( stack[ top ] != x ) {//清空 color [stack[ top ]] = col_num ; vis [ stack[ top-- ] ] = false ; } top -- ; } }
感谢大佬,向大佬低头。
//其实就是我不想把图片复制过来而已【微笑】
我博客里有大量的从别的博客复制过来的代码,分析,以及理解,但我一律会在文章后面标记原博客大佬博客名,其中部分会加以连接。
绝无抄袭的意思,只是为了我在复习的时候找博客方便。
如有原作者对此有不满,请在博客留言,我一定会删除该博文。