Tarjan算法用于寻找图G(V,E)中的所有强连通分量,其时间复杂度为O(|V|+|E|)。

  所谓强连通分量就是V的某个极大子集,其中任意两个结点u,v在图中都存在一条从u到v的路径。

  Tarjan的算法的流程是通过深度优先搜索遍历每个顶点,并且维护以下属性dfn,low,instk,p其中dfn表示该顶点第一次被访问时的次序,instk需要与一个栈stk配合使用,stk用于记录从某个顶点出发,尚未被包含进强连通分量的所有顶点,而instk用于记录一个顶点是否还存在于stk中,low表示从该结点出发可以访问到的所有在栈中的顶点中dfn属性最小的顶点的dfn值,p表示顶点所处强连通分量的代表顶点。

  算法的流程如下:

 tarjan(u, stk)
  if(u.dfn != 0)
    return
  u.dfn = order()
  u.low = u.dfn
  u.instk = true  
  stk.push(u)
  for (u, v) in E
    targin(v)
    if(v.instk)
      u.low = min(u.low, v.low)
  if(u.dfn == u.low)
    while(true)
      top = stk.pop()
      top.instk = false
      top.p = u
      if(top == u)
        break

  其中order()表示分配下一个次序号,要求order()方法的返回值随调用次数增加而递增,且不能少于1,可以通过维护一个计数器实现。我们需要对每个V中的顶点调用上述Tarjan流程即可保证强连通分量的正确分离。

  说明时间复杂度,由于每个结点被访问都会设置dfn值,因此一个结点最多只会被访问一次,其4~7行总执行次数不可能超过|V|。而8~11行中每次都会使用一条完全不同的边,其总执行次数不可能超过|E|。12~18行每次循环都会令一个顶点弹出stk,由于只有4~7行会向栈中压入一个顶点,因此总执行次数不会超过|V|。因此总的时间复杂度为O(|V|+|E|)。

  再说明算法正确性。从两个角度说明:1.任意两个连通顶点u,v都会拥有相同的p属性值,即u.p=v.p。2.任意两个不连通顶点都会拥有不同的p属性值。

  命题1:对于栈中的元素x,y,若x.dfn<y.dfn,则x必定在y之后出栈。因为dfn属性与入栈的顺序是一致的。

  命题2:若顶点x被加入栈中,则栈中所有现存顶点到x都有一条路径。假设当栈中所有顶点满足命题时,我们通过栈中的某个顶点y,将其后置顶点x加入到栈中,由于假设可知栈中y及y之下所有的顶点都能访问到x。对于y之上的第一个顶点z,若z不为x,则由于z在回溯到y时,没有从栈中弹出,故z.dfn>z.low,即z能访问到z之下的某个顶点,故z能访问到x。因此由归纳法可知命题成立。

  命题3:当我们确定了栈中某个顶点u的low值时,在栈中u之上所有的顶点和u必定处在同一个强连通分量中。假设当栈中所有顶点满足这一性质时,我们压入顶点u,并利用深度优先搜索算法遍历u的后置顶点。当我们确定了u的low值时,若在栈中u之上还存在顶点v,不妨设v为u之上的第一个顶点,显然v.dfn>u.dfn,即v的回溯应该发生在u回溯之前,而v没有被出栈,意味着v.low<v.dfn,即v能访问到栈中某个v之下的顶点z,v和u是连通的。依旧是使用了归纳法。

  对于1,不妨设u.dfn<v.dfn,由于v能访问到u,故v.low<=u.dfn,而由命题2知道,所有栈中v之下的顶点x都满足x.low<=v.low<=u.dfn,即v出栈时必定会导致u的出栈,故v.p=u.p。

  对于2,当u和v被设置相同的p值时,意味着二者同时出栈。而由命题3可知u和v必定是连通的。

  因此当我们对V中每个顶点调用Tarjan流程时,将会保证强连通分量的正确分离。

  

Tarjan的强连通分量算法的更多相关文章

  1. 【学习整理】Tarjan:强连通分量+割点+割边

    Tarjan求强连通分量 在一个有向图中,如果某两点间都有互相到达的路径,那么称中两个点强联通,如果任意两点都强联通,那么称这个图为强联通图:一个有向图的极大强联通子图称为强联通分量.   算法可以在 ...

  2. Tarjan求强连通分量,缩点,割点

    Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...

  3. CCF 高速公路 tarjan求强连通分量

    问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路. 现在,大臣们帮国王拟了一个修高速公路的 ...

  4. Tarjan求强连通分量、求桥和割点模板

    Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...

  5. UESTC 901 方老师抢银行 --Tarjan求强连通分量

    思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个D ...

  6. tarjan求强连通分量+缩点+割点以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  7. tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  8. HDU 1827 Summer Holiday(tarjan求强连通分量+缩点构成新图+统计入度+一点贪心思)经典缩点入门题

    Summer Holiday Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】

    Road Networks Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Stat ...

随机推荐

  1. ng $http 和远程服务器通信的一个服务。

    $http({url:'',method:''}).success().error() 简洁写法:$http.get()$http.post()... 注意事项:①要求返回的数据格式是json格式②在 ...

  2. 旧书重温:0day2【11】第6章 狙击windows的异常处理

    昨晚经过一番努力,又把第六章的内容温习了一遍! 随手,做了一个实验!狙击windows的异常处理, 顺便也把过程记录了下来!省事!(有图) 今早,论坛一直无法打开! 就推迟到了现在! 哈哈 正题: 第 ...

  3. HihoCoder - 1615矩阵游戏II(贪心)

    矩阵游戏II 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个NxN的整数矩阵,小Hi每次操作可以选择两列,将这两列中的所有数变成它的相反数. 小Hi可以进行任意 ...

  4. docker -ce(社区免费版)

    Docker -ce https://www.cnblogs.com/zhangxiaoyong/p/9706392.html Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以 ...

  5. 数据库模式显示的Swing表格

    http://code.google.com/p/simpleframework/ 是一个国内开源的JavaWeb框架,但其net.simpleframework.swing包里面提供了一个超强的Sw ...

  6. L3-008 喊山 (30 分)

    喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的.原来它是彝族先民用 ...

  7. ubuntu下网卡eth1如何修改为eth0

    正常来说,Linux在识别网卡时第一张会是eth0,第二张才是eth1.有时候我们使用虚拟机克隆技术后网卡的信息就会改变,新克隆出来的虚拟主机网卡名字可能变为eth1.无论我们怎么修改都无法改变,这就 ...

  8. php时间 显示刚刚 几分钟前等

    功能示例: $now = time();foreach($sys_res as $k => $v){ $day = intval(floor(($now - $v->system_time ...

  9. Linux Samba目录服务搭建与Java客户端访问

    前言: 本文比较简略,只求快速入门,若要了解详情,推荐一篇文章:http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.html 1,安装sa ...

  10. AngularJS:template

    ylbtech-AngularJS: 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   7.返回顶部   8.返回顶部   9 ...