图论学习六之Strongly connected components强连通分量

      强连通分量(Strongly connected cmponents)


在有向图G中,如果任意两个不同的顶点相互可达,则称该有向
  图是强连通的。有向图G的极大强连通子图称为G的强连通分支。


转置图: 将有向图G中的每一条边反向形成的图称为G的转置GT
原图GGT的强连通分支是一样的。

 

 

      有向连通分支的Tarjan算法


做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做
  开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最
  早的节点的开始时间。
初始时dfn[i]=low[i]


DFS过程中会形成一搜索树。在搜索树上越先遍历到的节点,显然dfn的值
  就越小。


DFS过程中,碰到哪个节点,就将哪个节点入栈。栈中节点只有在其所属的
  强连通分量已经全部求出时,才会出栈。


如果发现某节点u有边连到搜索树中栈里的节点v,则更新ulow 值为
dfn[v](更新为low[v]也可以)。

 

 

      有向图强连通分支的Tarjan算法


如果一个节点u已经DFS访问结束,而且
  此时其low值等于dfn值,则说明u可达的
  所有节点,都不能到达任何在u之前被
  DFS访问的节点 ---- 那么该节点u就是一
  个强连通分量在DFS搜索树中的根。


此时将栈中所有节点弹出,包括u,就找
  到了一个强连通分量

 

 

 

      EXAMPLE

lPOJ2186:Popular Cows

给定一个有向图,求有多少个顶点是由任何顶点出发都可达的。
N<=10000, M<=50000 

有向无环图中唯一出度为0的点,一定可以由任何点出发均可达
(由于无环,所以从任何点出发往前走,必然终止于一个出度为0
  的点

 

1. 求出所有强连通分量
2. 每个强连通分量缩成一点,则形成一个有向无环图DAG
3. DAG所有的点可达。那么该点所代表的连通分量上的所有的原图中
      的点,都能被原图中的所有点可达,则该连通分量的点数,就是答案。
4. DAG上面如果有不止一个出度为0的点,则这些G上面如果有唯一的
      出度为0的点,则该点能被点互相不可达,原问题无解,答案为

缩点的时候不一定要构造新图,只要把不同强连通分量的点染不
  同颜色,然后考察各种颜色的点有没有连到别的颜色的边即可(
  其对应的缩点后的DAG图上的点是否有出边)。

 

 

POJ-1236 Network of Schools

N个学校之间有单向的网络,每个学校得到一套软件后,可以通
  过单向网络向周边的学校传输。
问题1:初始至少需要向多少个学校发放软件,使得网络内所有
  的学校最终都能得到软件。
问题2:至少需要添加几条传输线路(),使任意向一个学校发放
  软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

2  <   N  <=  100

 

给定一个有向图,求:
  • 1) 求一个最小的顶点集,使得从这个顶点集出发,可以到达全部顶点
  • 2) 至少要加多少条边,才能从任何一个顶点出发,都能到达全部顶点

N <= 100

 

有用的定理

有向无环图中所有入度不为0的点,一定可以由
某个入度为0的点出发可达。

(由于无环,所以从任何入度不为0的点往回走,
必然终止于一个入度为0的点)

 

解题思路

1. 求出所有强连通分量
2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。
3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

 

在DAG上要加几条边,才能使得DAG变成强连通的,问题2
    的答案就是多少

加边的方法:
为每个入度为0的点添加入边,为每个出度为0的点添加出边

假定有 n 个入度为0的点, m个出度为0的点, max(m,n)就是
    第二个问题的解(证明难,略)

 

      Korasaju算法求有向图强连通分支


procedure Strongly_Connected_Components(G);
   begin
     1.深度优先遍历G,算出每个结点u的结束时间f[u],
      点如何选择无所谓。
     2.深度优先遍历G的转置图GT选择遍历的起点时,
      按照结点的结束时间从大到小进行。遍历的过程中,
      一边遍历, 一边给结点做分类标记,每找到一个新的
      起点,分类标记值就加1
     3. 2步中产生的标记值相同的结点构成深度优先森
       林中的一棵树,也即一个强连通分量
     end;
     证明参考:
     http://www.bioisland.com/Algorithm/ShowArticle.asp?ArticleID=58


(a)为有向图G,其中的阴影部分是G
     的强连通分支,对每个顶点都标出
     了其发现时刻与完成时刻,黑色边
     为深度优先搜索的树枝;


(b)G的转置图GT 依次以b,c,g,h为起
     点做DFS, 得到4个强连通分量

 

 

      算法复杂度分析


深度优先搜索的复杂度:Θ(V + E)
计算GT的复杂度:0或者Θ(V + E)(临接表)
所以总的复杂度为:Θ(V + E)
非常好的算法!

 


 

如果你不开心,那我就把右边这个帅傻子分享给你吧,
你看,他这么好看,跟个zz一样看着你,你还伤心吗?
真的!这照片盯上他五秒钟就想笑了。
一切都会过去的。
时间时间会给你答案2333

 

posted @ 2018-07-20 09:45  孟东行#  阅读(528)  评论(0编辑  收藏  举报