tarjan

 tarjan基于这样一个定理:
在任何深度优先搜索中,同一强连通支内的所有顶点均在同一棵深度优先树中。也就是说,强连通分量一定是有向图的某个深搜树子树。

既然强连通分量是深搜树的一棵子树,要找到一个分量,只要找到树根( 连接不同分量的桥的前端顶点) ,然后取出其所属分量的顶点即可。

   引理:白色路径定理:
在一个有向或无向图G=(V,E)的深度优先森林中,结点v是结点u的后代当且仅当在搜索发现u的时刻d[u],从结点u出发经一条仅由白色结点组成的路径可达v。

  所以,tarjan算法可以在线性时间内求出一个图的强连通分量,伪代码如下:

stack s;
graph G;
int dex;
tarjan(结点 u)
{
 low(u) = dfu[u] = dex++;
 s.push(u);
 for (每一个 结点u 能到达的 结点v)
 {
  if(v 没有被搜到)
  {
   tarjan(v);
   low[u] = min(low[u],low[v]);
  }
  else
   low[u] = min(low[u],dfu[v]);
 }
 if (low[u] == dfu[u])
   出栈直到元素为u;
}

当然,实际操作的时候会麻烦一点,实际用的时候一般伴随连通环压缩成点,加上求环的度,这都是一些技巧的问题了,就不再多说了!

今天用十字链表写了pku 2186题竟然用了400多ms,太失败了!郁闷。。。。

你可能感兴趣的:(tar)