求极大强连通分量的Tarjan算法

首先,在有向图G中,如果两个顶点vi,vj间(vi<>vj)都有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components),如果一个强连通分量中不再能加入任何一个顶点,则这个强连通分量是一个极大强连通分量。

由上面的定义,可以知道,强连通分量中各点可以互相到达,则我们可以找到每个极大强通分量的“根结点”,再通过从底层节点向上推的方法求出一个极大强连通分量,所以关键在于求出根结点,所以这里加入两个数组,dfn,和low,其中dfn为搜索序号,表示第几个搜到该点,而low表示该节点向上最远可以回到的节点,显然当一个节点的dfn[i]=low[i]时,它就是这一个极大强连通分量的根,之后搜索到的点包含在这个极大强连通分量中,下面就要考虑一下如何取出这个极大强连通分量,于是维护一个栈,每搜索一个节点,就把它压入栈中,那么当我们发现根结点时,在它后面入栈的都是它代表的极大强连通分量中的节点,只需要弹栈直到根结点出栈即可。

【程序伪代码】

Dfs(k)

Inc(time);    //搜索的序号变量

Low[x]=time   //当前节点最远可以回到的点的时间戳

Dfn[x]=time    //时间戳

Push(x)   //入栈

Instack[x]=true   //将x节点在栈中标记为真

For i=x的所有儿子

If 没有访问过 x   //还没有被搜索过

Dfs(i)

Low[x]=Min(low[x],low[i])

//搜索之后发现儿子节点能到达的最早时间戳比x要早,则更新

Else //已经搜索过

If  (i在栈中)and(dfn[i]<low[x])

//在栈中说明属于同一个强连通分量,而如果时间戳更早,显然需要更新

Low[x]=dfn[i]

If dfn[x]=low[x] //如果该节点是一个强连通的根结点

Inc(num) //强连通数增加

While true do

Pop //弹出该强连通的结点

Instack[stack[top]]=false//在栈内标记为假

If stack[top+1]=x//如果根结点已经输出

Break //跳出

View Code

 1 program targan(input,output); 2  type 3    node = ^link; 4    link = record 5      goal : longint; 6      next   : node; 7   end; 8 var 9    stack   : array[1..1000] of longint;10    l    : array[1..1000] of node;11    instack : array[1..1000] of boolean;12    dfn    : array[1..1000] of longint;13    low    : array[1..1000] of longint;14    ans    : array[1..1000] of longint;15    num,e   : longint;16    m,n,top,cnt    : longint;17 procedure add(x,y: longint );18 var19    t : node;20 begin21    new(t);22    t^.goal:=y;23    t^.next:=l[x];24    l[x]:=t;25 end; { add }26 procedure init;27 var28    i,x,y : longint;29 begin30    readln(n,m);31    cnt:=0;32    for i:=1 to n do33       l[i]:=nil;34    fillchar(instack,sizeof(instack),false);35    for i:=1 to m do36    begin37       readln(x,y);38       add(x,y);39    end;40 end; { init }41 procedure dfs(x :longint );42 var43    t : node;44 begin45    inc(cnt);46    dfn[x]:=cnt;47    low[x]:=cnt;48    inc(top);49    stack[top]:=x;50    instack[x]:=true;51    new(t);52    t:=l[x];53    while t<>nil do54    begin55      if dfn[t^.goal]=0 then56      begin57      dfs(t^.goal);58      if low[t^.goal]<low[x] then59         low[x]:=low[t^.goal];60      if dfn[t^.goal]<low[x] then61         low[x]:=dfn[t^.goal];62      end63      else64    if (instack[t^.goal]=true)and(dfn[t^.goal]<low[x]) then65    begin66      low[x]:=dfn[t^.goal];67    end;68       t:=t^.next;69    end;70    if low[x]=dfn[x] then71    begin72       inc(num);73       while true do74       begin75         ans[stack[top]]:=num;76         instack[stack[top]]:=false;77         dec(top);78         if stack[top+1]=x then79            break;80        end;81    end;82 end; { dfs }83 procedure print;84 var85    i : longint;86 begin87    for i:=1 to n do88       write(ans[i],'');89 end; { print }90 begin91    init;92    for e:=1 to n do93       if dfn[e]=0 then94          dfs(e);95    print;96 End.

转载于:https://www.cnblogs.com/neverforget/archive/2011/10/13/2209611.html

极大强连通分量的Tarjan算法相关推荐

  1. CSP认证201509-4 高速公路[C++题解]:强连通分量、tarjan算法模板题

    题目分析 来源:acwing 分析: 所求即为强连通分量的个数,然后计算每个强连通分量中点的个数,相加即可. 所谓强连通分量,它是一个子图,其中任意两点可以相互到达,并且再加一个点,就不能满足任意两点 ...

  2. 有向图强连通分量的Tarjan算法——转自BYVoid

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  3. [转载] 有向图强连通分量的Tarjan算法 ——byvoid

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  4. 有向图强连通分量的Tarjan算法

    有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大 ...

  5. 有向图强连通分量之Tarjan算法

    出处https://www.byvoid.com/zhs/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...

  6. 寻找强连通分量的Tarjan算法

    有向图的强连通分量 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大 ...

  7. 算法提高课-图论-有向图的强连通分量-AcWing 367. 学校网络:强连通分量、tarjan算法

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 第一问:通过tarjan算法求出强连通分量并且缩点后,统计入度为0的点的个数p即可. 第二问,至少加几条边才能使图变成强连通分量?这 ...

  8. 图论——强连通分量(Tarjan算法)

    文章目录 强连通分量 利用Tarjan算法求强连通分量 来一道例题练手(USACO08DEC) 图论文章汇总 强连通分量 什么是强连通图? 如果一个有向图中,存在一条回路,所有的结点至少被经过一次,这 ...

  9. 算法提高课-图论-有向图的强连通分量-AcWing 1174. 受欢迎的牛:tarjan算法求强连通分量、tarjan算法板子、强连通图

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 强连通图:给定一张有向图.若对于图中任意两个结点x,y,既存在从x到y的路径,也存在从y到x的路径,则称该有向图是"强连通 ...

  10. 连通分量、强连通分量与Tarjan算法

    [定义] 对于一个有向图GGG,其连通分量为:对于分量中任意两点u,vu,vu,v,必然可以从uuu走到vvv,且从vvv走到uuu. 强连通分量就是极大连通分量.即一个连通分量加上任何一些点之后它都 ...

最新文章

  1. web项目获取运行时...\WEB-INF\classes目录下文件
  2. Deepmind顺练了人工智能14天成为星海2最强玩家
  3. 可视化-echarts流向图制作及recharts
  4. 产品管理必修课:发布新版本不等于改进产品
  5. 明天要中秋节了,先来到简单“类”的题目
  6. 创建链表和遍历链表算法演示
  7. ba控制系统的服务器,01-正文
  8. 佳明或已支付勒索金,获得 WastedLocker的解密密钥
  9. php里面求坐标的间距,php如何计算两坐标点之间的距离
  10. 王通:网络营销人才必备的10种技能
  11. ElasticSearch常用的几种查询方式
  12. android图标分组名称唯美简单可复制,扣扣分组名称简单唯美
  13. [源码和文档分享]基于QT的英文文献的编辑与检索系统的实现
  14. 四位共阳极数码管显示函数_求各位大神指正,四位一体共阳极数码管数字钟程序,仿真能运行,实物就只显8个8,不动...
  15. Java程序在结构上的特点_下面关于JavaApplication程序结构特点描述中,错误的是()...
  16. 谷歌地球out了,谷歌火星来了!
  17. 【Busybox】Busybox源码分析-04 | ash和login程序
  18. 浅谈从信息化到数字化时代下的业财一体化
  19. 计算机主机后面的usb哪个不可接入,电脑主机上的USB介面前面有两个,后面有四个,但是只能用两个...
  20. android锁屏快捷键设置,Android4.0+锁屏程序开发——设置锁屏页面篇

热门文章

  1. python 生成器_Python生成器
  2. angular 9.2升级10.2.2
  3. c#服务器后台搭建_微信影视小程序搭建拆解:第一课,影视小程序简介,搭建影视小程序的整体流程...
  4. android 显示多条数据格式,Multipart上传的进度条,包含多个Android文件
  5. redis常用内容信息:
  6. 核磁谱图分析步骤_微谱技术:想要涂料开发,少不了仪器分析……
  7. mysql ip 远程连接不上_【技术贴】解决MySql连接不上 ip远程连接Host is not allowed to conn-阿里云开发者社区...
  8. Tensorflow笔记:MNIST数据集输出手写数字识别准确率
  9. 设计模式学习02:简单工厂模式、工厂模式以及抽象工厂模式(具体)
  10. Dockerfile 数据卷最佳实践