打算开始重新复习一遍相关算法。对于有向图tarjan算法,通过学习过很多说法,结合自己的理解,下面给出算法自己的观点。

算法总模型是一个dfs,结合一个stack(存放当前尚未形成SCC的点集合),记录下俩个数组:

dfn【i】:结点i的访问时间戳。 low[i]:i结点所能到达的祖先。

主要是俩次对low【u】的更新,一次:回溯的时候,u的孩子结点(vv)对u的更新,

  if(low[vv]<low[u])low[u]=low[vv];  //孩子可以到达,我必然也可以到达。

二次:

  if(dfn[vv]<low[u])low[u]=dfn[vv]; //能到达的祖先,所以更新。

这里“祖先”,表面上看是孩子,其实是某个祖先结点。

若每次访问对u的孩字访问结束:若u满足

if(dfn[u]==low[u])    

则 以u为根,stack中u以及u上的点必然形成以个SCC。

个人证明如下:

1.u必然可以到达u的所有孩子,此时就是栈中u之上的点。这个毋庸置疑。

2.下面只需证明所有孩子都可以到达u:

对任意点(stack中在u之上的) i,必有dfn[i]>low[i],(若相等必然已经弹栈),i到达low[i]=dfn[j]<low[j]=dfn[k]<low[p].......,一直递减,其中i,j,k,p...代表不断找可达的祖先,

知道到u为止(递减有下界),所以任意结点都可以到u。

即证明了是u以上已经u是一个SCC。

额外说明几点(易误点):

1,:low值相同的点一定在同一个scc中,毋庸置疑的这个。

2:同一个SCC中的点的LOW值未必都相同,是因为更新有先后的问题(可以举例)。但是除根外,其他点dfn>low,这个显然。

对于无向图,只需要把边改为双向边即可,这时候,(无向图详细待更新)。

hdu1269题意:判断有向图是否是强连通。直接用tarjan算法即可,只有一个SCC(强连通分量)。

给出核心代码已经详见:(有向图涉及强连通的,要用栈)

void tarjan(int u)
{
dfn[u]=low[u]=++times; //时间戳的标记
instack[u]=1;
s.push(u);
for(int i=0;i<v[u].size();i++)
{
int vv=v[u][i];
if(!vis[vv])
{
vis[vv]=1;
tarjan(vv);
if(low[vv]<low[u])low[u]=low[vv]; //孩子可以到达,我必然也可以到达。
}
else if(instack[vv]) //注意,更新时要有在栈中条件,代表该孩子(其实是祖先)我能到达,而且是属于当前SCC。
{
if(dfn[vv]<low[u])low[u]=dfn[vv]; //能到达的祖先,所以更新。
}
}
if(dfn[u]==low[u]) //是一个scc的根节点,出栈,一发现就出栈。
{ int cur;
          num++
       do
{
cur=s.top();
s.pop();
instack[cur]=0;
          SCC[cur]=num;                         //这里可以完成缩点工作。
}while(cur!=u);
}
}

有向图tarjan算法求连通分量的粗浅讲解、证明, // hdu1269的更多相关文章

  1. [Tarjan系列] Tarjan算法求无向图的双连通分量

    这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...

  2. Tarjan算法求有向图强连通分量并缩点

    // Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...

  3. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  4. Tarjan算法求割点

    (声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...

  5. 浅谈 Tarjan 算法之强连通分量(危

    引子 果然老师们都只看标签拉题... 2020.8.19新初二的题集中出现了一道题目(现已除名),叫做Running In The Sky. OJ上叫绮丽的天空 发现需要处理环,然后通过一些神奇的渠道 ...

  6. HDU 1269 迷宫城堡 tarjan算法求强连通分量

    基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等, ...

  7. [学习笔记] Tarjan算法求桥和割点

    在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...

  8. ZOJ Problem - 2588 Burning Bridges tarjan算法求割边

    题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...

  9. POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)

    题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...

随机推荐

  1. python基础面试题整理---从零开始 每天十题(04)

    一.Q:如何用Python来进行查询和替换一个文本字符串? A:可以使用sub()方法来进行查询和替换,sub方法的格式为:sub(replacement, string[, count=0]) re ...

  2. MySQL查询当天数据以及大量查询时提升速度

    select * from 表名 where to_days(字段名) = to_days(now()) 一.数据库设计方面1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...

  3. vuejs 的错误代码,有助于理解

    1.vuejs 的双向绑定理解 2.嵌套复杂对象的使用. * 1. 分割都是, 2. json 中分割都是; 4. v-bind:value="param" 括号内的就是 vuej ...

  4. CF-1110 (2019/02/08)

    CF-1110 A. Parity 快速幂的思想,考虑最后一位即可 #include <bits/stdc++.h> using namespace std; typedef long l ...

  5. vue-music:歌词的其他功能

    由于歌词的播放需要歌曲播放,切换歌曲,歌曲的播放模式等等有关联,因此,需要在这几处处理相关问题 1.循环播放回不到开始位置 loop() { this.$refs.audio.currentTime ...

  6. 《UNIX环境高级编程》笔记——4.文件和目录

    一.引言 本章描述文件系统的其他特征和文件的性质.有些背景知识需要注意,例如用户ID与文件权限.文件系统等. 二.函数stat.fstat.fstatat和lstat #include <sys ...

  7. bash初识,特性,用法/网站

    目录 一.Bash初识 Bash Shell介绍 Bash Shell的作用 Bash 两种方式 命令提示符 二.Shell的基本语法 三.Shell的基本特性 1.命令补全 tab 2. Linux ...

  8. LeetCode695--岛屿的最大面积

    ''' 岛屿的最大面积 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着 ...

  9. bs4--官文--修改文档树

    修改文档树 Beautiful Soup的强项是文档树的搜索,但同时也可以方便的修改文档树 修改tag的名称和属性 在 Attributes 的章节中已经介绍过这个功能,但是再看一遍也无妨. 重命名一 ...

  10. git 打补丁,即git review之后需要二次修改并提交代码

    假如代码已经push上去了,可是当review时,发现有地方需要修改,你可以继续在本地修改你的文件,之后git status查看修改的文件,然后git add修改的文件,此时不能直接git commi ...