Tarjan算法的伪代码实现 及 求割点的思路浅谈
1Tarjan算法求强连通分量
设置DFN[], LOW[],数组进行搜索。DFN[S],代表S的时间戳, 也就是S的地位。而LOW[S]代表S能追寻的先祖节点的时间戳,把未放入过的节点放入栈中, 如果搜到底回溯时发现DFN[S] = LOW[S], 那么便把栈中包括S和S之后的节点弹出, 这些节点便是一个连通分量。
Tarjan算法的伪代码实现
Void tarjan(int S)
{
Stack.push(S); // 把S放入栈中。
Vis[S] = 1;// 表示S节点在栈中。
DFN[S] = LOW[S] = ++FLAG // 初始化时间戳及先祖地位。
For( T 属于 S的son) // 遍历所有S的子节点。
If(vis[T] == 0) // 如果 T 不在栈中
{
Tarjan(T); //继续向下搜索。
LOW[S] = MIN(LOW[S], LOW[T]). //更新S节点的先祖地位。
}
Else if(vis[T] == 1) //S节点 正在栈中。
{
LOW[S] = MIN(LOW[S], DFN[T]). // 更新S节点的先祖地位。
}
If(LOW[S] == DNF[S]) // 如果 S节点的先祖地位就是他自己 那么他就是一个强连通分量的ROOT。
{
DO{
Pop T // 弹出T
Vis[T] = 2; // 表示T节点已经进入过并弹出
T = stack.top; //更新T
}While(S != T) // 一直弹到本强连通分量的ROOT为止。 弹出的节点便是一个强连通分量。
}
}
2Tarjan算法求割点
1. 如果S这个节点是根节点, 并且他有两个或两个以上的子节点, 那么S节点必然是割点。
2, 如果S节点不是根节点, 那么我们可以设置DFN[], LOW[],数组进行搜索。 DFN[S],代表S的时间戳, 也就是S的地位。而LOW[S]代表S能追寻的先祖节点的时间戳, 如果用Tarjan算法实现, 发现关于S节点存在S节点的子节点T,T的LOW[T] >= DFN[S], 也就是说T的最高先祖地位不超过S节点, 那么S节点断了, T和T之后的节点便会与之前的图断开, 所以S便为割点。
注:这些都是我自己的想法,不一定精准, 如有错误, 请各位大牛指出, 谢谢。