Tarjan的学习笔记 求割边求割点

摘要:
所以我决定学习tarjan算法。切割点和切割边的概念不再重复。Tarjan可以找到线性时间复杂度的临界点。定理对于其他节点,如果其子节点的相对侧不指向其祖先,则它是切点。证明是显而易见的,因为无向图不穿过子树的边=Fa){low[u]=min;}}}如果从树的根开始,则有两个以上的节点,而不是切割边。

博主图论比较弱,搜了模版也不会用。。。

所以决心学习下tarjan算法。

割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边。

重要的概念:时间戟,就是一个全局变量clock记录访问结点的时间。一个无向图dfs会形成一个森林,当图只有一个连通分量时,就只有一棵树。

由于在无向图中,除了树边,其他都是反向边。可以画个图感受一下,可以反证的,如果有其他类型的边,那么dfs先沿着那些边跑图的,那么那些边就不存在。

如果结点是树根,那么它是割点的充要条件就是它有两个子结点。

定理

对于其他结点,如果他的子结点的反向边没有指向它的祖先的,那么它就是割点。证明很明显,因为无向图是没有横跨子树的边的。(对树根不成立哦~)

具体判断的时候借助时间戟,定义low(u)为u和其后代所能返回最早祖先的的dfn值,那么定理就可以等价的转化为low(v)>=pre(u)。而且如果v的后代只能返回自己,那么删除(u,v)的一条边就可以让图分连通,那么就找到了割边(桥)。

伪代码

int dfs(int u,int fa) 返回u的low值, fa是判断是不是树边的二次访问
{
  记录时间戟并初始化u的low值

  跑图{
  如果子节点v没访问过{
  dfs(v)并返回后代low值 
  用后代low值更新u的low值    
  如果 后代的low值>=pre       //根据要求的是割边还是割点替换判断条件

    那么u是割点           //用数组记录,因为一个割点,条件可能不只成立一次
  }否则 如果是反向边         // 一.要满足v的时间戟小于u的,二.v不是u的父节点(是无向图的边的二次访问)

     {
       用反向边更新u的low值 
     }
  }

  用数组记录low u

  返回 low u
}

对于树根可以特判,可以通过对代码的小改动来实现,做法是记录子结点数量child,初始调用时fa赋值-1,加一个判断fa<0且child == 1时iscut(u) = false

 这个不能跑重边

对于有重边的图可以采用以下技巧

如果是用前向星存正反两条边是相邻并且奇偶性一定是不一样的,那么可以利用异或的开关性,来判断是不是树边if(i==(id^1))continue;//不从i对应的边到父节点  

void tarjan(int u,int fa)
{
    dfn[u] = low[u] = ++clock;
    for(int i = head[i]; ~i ; i = nxt[i]){
        int v = to[i];
        if(!dfn[v]){
            tarjan(v,u);
            low[u] = min(low[u],low[v]);
            if(low[v] > dfn[u]){
                ans = min(ans,wei[i])
            }
        }else if(v != fa) {
            low[u] = min(low[u],dfn[v]);
        }
    }
}

 如果从树根出发的话,那么有两个以上的结点,反而不是割边。(具体看想要连通哪里)

免责声明:文章转载自《Tarjan的学习笔记 求割边求割点》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇机器学习笔记19-----LDA主题模型(重点理解LDA的建模过程)Oracle Cursor的使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

TarJan 算法求解有向连通图强连通分量

[有向图强连通分量] 在有向图G中,如果两个 顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,...

Tarjan 算法详解

刚学的一个 新算法,终于有时间来整理一下了。 想必都对著名的 ‘太监’ 算法早有耳闻了吧。 TarjanTarjan 算法是一种求解有向图强连通分量的算法,它能做到线性时间的复杂度。 实现是基于DFS爆搜,深度优先搜索一张有向图。!注意!是有向图。然后根据树,堆栈,打标记等种种神奇扯淡方法来完成拆解一个图的工作。 如果要理解Tarjan,我们首先要了解一下...

Tarjan求割点

概述 在一个无向图中,若删除某个点u后连通分量数目增加,则称点u为该无向图的一个割点(cut vertex) 引理 无向连通图DFS树 从一个节点出发进行DFS,将后访问的结点设为前访问结点的孩子,DFS经过的边叫做DFS树的树边(tree edge),第一次处理时从后代(descendant)指向祖先(ancestor)的边叫做返祖边(back edge...

深度优先生成树及其应用

在上一篇博客判断有向图是否有圈中从递归的角度简单感性的介绍了如何修改深度优先搜索来判断一个有向图是否有圈。事实上, 它的实质是利用了深度优先生成树(depth-first spanning tree)的性质。那么什么是深度优先生成树?顾名思义,这颗树由深度优先搜索而生成的,由于无向图与有向图的深度优先生成树有差别,下面将分别介绍。 一. 无向图的深度优先生...