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]
    	}
    }
    
  • 相关阅读:
    checkbox 实现单选效果(html)
    HDU-6850 Game
    牛客练习赛29----F 算式子
    牛客多校第二场 B Boundary
    D. Omkar and Circle
    【洛谷】P3306 [SDOI2013]---- 随机数生成器
    二次剩余
    【洛谷】--P2704 [NOI2001]炮兵阵地
    【洛谷】4310 绝世好题
    快速排序
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CutPoint_and_Bridge.html
Copyright © 2011-2022 走看看