zoukankan      html  css  js  c++  java
  • Tarjan在图论中的应用(二)——用Tarjan来求割点与割边

    前言:(Tarjan)

    割点割边建立在 (Tarjan)算法的基础之上,因此建议在看这篇博客之前先去学一学(Tarjan)

    回顾(Tarjan)中各个数组的定义

    首先,我们来回顾一下(Tarjan)中各个数组的定义:

    (dfn[) (]):每个点的(dfs)序。

    (low[) (]):每个点能到达的(dfs)序最小的节点的(dfs)序。

    而其他数组在求割点和割边的过程中则不太必要了。

    割点

    首先,我们要了解一下割点的定义把这个点去掉之后,这个点所在的联通块就会被分成若干个联通块

    既然这样,也就是说,只要这个节点某一个子节点所到达的节点的(dfs)序大于等于该节点的(dfs)序,即它的这个子节点无法到达(dfs)序小于该节点的节点,就说明它是一个割点了。

    而对于一个联通块第一个访问的节点,则需特判,如果它在遍历完一个节点所能遍历到的所有节点,还能找到没有被遍历过的节点,就说明它是一个割点。

    代码如下:

    inline void Tarjan(int x,int lst)//Tarjan求割点
    {
    	register int i,tot=0;//tot记录访问到的子节点个数
    	for(dfn[x]=low[x]=++d,i=lnk[x];i;i=e[i].nxt)//枚举每一个子节点
    	{
    		if(!(e[i].to^lst)) continue;//如果这个节点是当前节点的父亲节点,就跳过
    		if(!dfn[e[i].to])//如果这个子节点没有被访问过 
    		{
    			Tarjan(e[i].to,x),low[x]=min(low[x],low[e[i].to]),++tot;//遍历该子节点,更新low[x],并将tot加1
    			if(lst&&low[e[i].to]>=dfn[x]) IsCut[x]=1;//如果当前节点不是一个联通块第一个访问的节点,且当前节点的这个子节点dfs序大于等于当前节点的dfs序,那么就说明当前节点是割点
    		}
    		else low[x]=min(low[x],dfn[e[i].to]);//更新low[x]
    	}
    	if(!lst&&tot>=2) IsCut[x]=1;//如果当前节点是联通块第一个节点,且访问到的子节点个数≥2,那么就说明当前节点是割点
    }
    

    割边

    还是一样,先了解一下割边的定义把这条边去掉之后,这条边所在的联通块就会被分成若干个联通块,看起来与割点的定义很像。

    因此,如果一条边所连接的两个节点,若其中(dfs)序较大的节点不经过这条边所能到达的(dfs)序最小的节点大于这条边连接的点中(dfs)序较小的节点,就说明这条边是一条割边。

    不过还要注意判重的情况,要注意如果有两条相同的边,那么这两条边肯定都不是割边。

    代码如下:

    inline void Tarjan(int x,int lst)//Tarjan求割边
    {
    	register int i,flag=1;//flag记录当前节点是否第一次访问它的父亲节点
    	for(dfn[x]=low[x]=++d,vis[Stack[++top]=x]=1,i=lnk[x];i;i=e[i].nxt)//枚举每一个子节点
    	{
    		if(flag&&!(e[i].to^lst)) {flag=0;continue;}//如果是第一次访问父亲节点,就将flag标记为0,并跳过这条边
    		if(!dfn[e[i].to])//如果这个子节点没有被访问过
    		{
    			Tarjan(e[i].to,x),low[x]=min(low[x],low[e[i].to]);//访问这个节点,并更新low[x]
    			if(low[e[i].to]>low[x]) IsBridge[i]=1;//如果这条边连向的另一个节点所能到达的dfs序最小的节点大于该节点的dfs序,就说明这条边是割边
    		}
    		else if(vis[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);//否则,更新low[x]
    	}
    }
    
  • 相关阅读:
    计算机世界中解决问题的三种技术手段
    应用程序池的经典模式与集成模式的区别
    sh文件的编译
    flex学习开始了
    com,ActiveX,Ole之间的关系学习总结
    "正在等待localhost。。”问题的解决
    一些感悟
    面向对象软件工程方法学实践【转】
    外连接在sqlserver和access之间的差异
    外连接在sqlserver和access之间的差异
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CutPoint_and_Bridge.html
Copyright © 2011-2022 走看看