我的Tarjan总结.docVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
我的Tarjan总结

Contents: ?一、连通图和连通分量 ?二、强连通图和强连通分量 三、Tarjan算法思想 首先,说一下基础概念。 一、连通图和连通分量 1.顶点间的连通性 在无向图G中,若从顶点vi到顶点vj有路径 当然从vj到vi也一定有路径 ,则称vi和vj是连通的。 2.连通图 若V G 中任意两个不同的顶点vi和vj都连通 即有路径 ,则称G为连通图 Con-nected Graph 。 3.连通分量 无向图G的极大连通子图称为G的连通分量 Connected Component 。 ??注意:    任何连通图的连通分量只有一个,即是其自身 非连通的无向图有多个连通分量。 二、强连通图和强连通分量 1.强连通图 有向图G中,若对于V G 中任意两个不同的顶点vi和vj,都存在从vi到vj以及从vj到vi的路径,则称G是强连通图。 2.强连通分量 有向图的极大强连通子图称为G的强连通分量。 注意: 强连通图只有一个强连通分量,即是其自身。 非强连通的有向图有多个强连分量。 下面 三、Time 0; dfs v : low[v] dfn[v] time ++; stack.push v ; 扫描v能直接到达的顶点k,如果k没被访问过那么先dfs k ,low[v] min low[v],low[k] ;如果k已经被访问了,则low[v] min low[v],dfn[k] (就是这里使low[v]不一定最小,但不会影响这里low[v] 会小于dfn[v])。 扫描完所有k后,若low[v] dfn[v],则stack里v以上的所有元素出栈,则出栈的就是极大强连通分量。 四、Tarjan算法证明: 1. 在栈里,当dfs遍历到v,而且已经遍历完v所能直接到达的顶点时,low[v] dfn[v]时,v一定能到达栈里v上面的顶点: 因为当dfs遍历到v,而且已经dfs递归调用完v所能直接到达的顶点时(假设上面没有low dfn),这时如果发现low[v] dfn[v],栈上面的顶点一定是刚才从顶点v递归调用时进栈的,所以v一定能够到达那些顶点。 2 .dfs遍历时,如果已经遍历完v所能直接到达的顶点而low[v] dfn[v],我们知道v一定能到达栈里v上面的顶点,这些顶点的low一定小于 自己的dfn,不然就会出栈了,也不会小于dfn[v],不然low [v]一定小于dfn[v],所以栈里v以其v以上的顶点组成的子图是一个强连通分量,如果它不是极大强连通分量的话low[v]也一定小于dfn[v](这里不再详细说),所以栈里v以其v以上的顶点组成的子图是一个极大强连通分量。 五、Tarjan算法的时间复杂度分析 因为所有的点都刚好进过一次栈,所有的边都访问的过一次,所以时间复杂度为O(n+m)。 六、Tarjan算法参考代码 #include #include #include #define MAX 4001 using namespace std; int Stop;//栈中的元素个数 int cnt;//记录连通分量的个数 int visitNum;//记录遍历的步数 int DFN[MAX]; //记录节点u第一次被访问时的步数 int LOW[MAX]; //记录与节点u和u的子树节点中最早的步数 bool instack[MAX];//记录节点u是否在栈中 int Stap[MAX];//栈 int Belong[MAX];//记录每个节点属于的强连通分量编号 int N;//节点个数 vector tree[MAX]; void tarjan int i int j; DFN[i] LOW[i] ++visitNum; instack[i] true; Stap[++Stop] i;//将当前节点压入栈中 for unsigned k 0;k tree[i].size ;k++ j tree[i][k]; if !DFN[j] //j还没有被访问过 tarjan j ; //父节点是子节点的子节点 if LOW[j] LOW[i] LOW[i] LOW[j]; //与j相连,但是j已经被访问过,且还在栈中 //用子树节点更新节点第一次出现的时间 else if instack[j] DFN[j] LOW[i] LOW[i] DFN[j]; //节点i是强连通分量的根 if DFN[i] LOW[i] cnt++; //输出找到的强连通分量 cout 连通分量 cnt : ; //退栈,直至找到根为止 do j Stap[Stop--]; instack[j] false; cout j ; Belong[j]

文档评论(0)

kabudou + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档