伪代码:
tarjan(int u){
dfn[u] = low[u] = ++cnt; //表示第几次访问到
vis[u] = 1;//标记入栈
sta.push(u) //顶点入栈
for(u:v) //从u中取出v的子节点 在图中 就是查找u的连接点
if(!vis[v]) //如果顶点 v没有入栈
tarjan(v)
low[u] = min(low[u] , low[v])
else if (vis[v])//如果顶点v已入栈
low[u] = min(dfn[u] , low[v]);
if dfn[u] == low [u] //如果访问的顺序 与low [u]值相同 比如: 回溯的顶点1 而 最小的分量 low[u] 等于本身 那么就对他进行出栈操作
int v = sta.top; //获取 栈顶元素
printf v;//打印顶点v 表示与u顶点联通
sta .pop //出栈
while( u!=v) // u!=v 表示在弹出时,出栈的顶点v不能等于 u 否则 联通分量只有自身
//因为在弹出时如果没弹出到 自身 会把与u联通分量弹出来,直到 u ==v就不再弹出
例如 1 2 3 6 时 因为只有自身顶点 所以6的联通分量只有自己 3也是如此。
当栈内元素有 1 2 5 4 时 回溯到 顶点1 而顶点1 刚好等于dfn[1] == low [1] 所以会对他进行出栈 4 5 2 1
附个例子来理解。
例子输入:
6 7
1 2
2 3
2 5
1 4
4 5
3 6
5 1
6
3
4 5 2 1