首页 > 其他分享 >图论-割点与割边

图论-割点与割边

时间:2024-05-09 22:14:59浏览次数:17  
标签:图论 割边 int back 割点 dfn && iscut

这是摘自算法书上的一篇 Tarjan 求割点算法

dfn[i] 代表时间戳数组
back[i] 代表该点 不依靠祖先节点 能回到的最远的祖先节点

采用链式前向星建图,结果存储在 iscut[ ] 数组中


点击查看代码
int head[N], cnt = 0;
struct Edge{
    int from, to, nxt;
}e[N << 1];
void add(int u, int v){
    e[++cnt].from = u;
    e[cnt].to = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

int dfn[N], back[N], tim; // dfn[i] 时间戳  back[i] 回退到祖先
bool iscut[N]; // 结果数组

void dfs(int u, int fa){
    dfn[u] = back[u] = ++tim;
    int child = 0;
    for(int i = head[u]; i != 0; i = e[i].nxt){
        int v = e[i].to;
        if(!dfn[v]){
            // v 没访问过
            child++;
            dfs(v, u);
            back[u] = min(back[u], back[v]);
            if(back[v] >= dfn[u] && u != 1)
                iscut[u] = true;
        }
        else if(dfn[v] < dfn[u] && v != fa){
            back[u] = min(back[u], dfn[v]); // 注意不是  back[v]
        }
    }
    if(u == 1 && child >= 2){
        iscut[u] = true;
    }
}

后来敲的时候,有一行代码为 back[u] = min(back[u], dfn[v]);容易误写为back[u] = min(back[u], back[v]
此时就要重视 back[ ] 表示 不依靠祖先节点

当然,这个稍微改动下,就是割边


点击查看代码
int head[N], cnt = 0;
struct Edge{
    int from, to, nxt;
}e[N << 1];
void add(int u, int v){
    e[++cnt].from = u;
    e[cnt].to = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

int dfn[N], back[N], tim; // dfs[i] 时间戳  back[i] 回退到祖先
bool iscut[N << 1]; // 结果数组

void dfs(int u, int fa){
    dfn[u] = back[u] = ++tim;
    int child = 0;
    for(int i = head[u]; i != 0; i = e[i].nxt){
        int v = e[i].to;
        if(!dfn[v]){
            // v 没访问过
            child++;
            dfs(v, u);
            back[u] = min(back[u], back[v]);
            if(back[v] > dfn[u] && u != 1)
                iscut[i] = true;  // 边为
        }
        else if(dfn[v] < dfn[u] && v != fa){
            back[u] = min(back[u], dfn[v]); // 注意不是  back[v]
        }
    }
    if(u == 1 && child >= 2){
        for(int i = head[u]; i != 0; i = e[i].nxt){
            iscut[i] = true;
        }
    }
}

至于这份割边代码,iscut数组记录的倒是有些奇怪,但也能输出边的信息

标签:图论,割边,int,back,割点,dfn,&&,iscut
From: https://www.cnblogs.com/9102qyy/p/18183165

相关文章

  • 24/05/08 图论
    \(\color{purple}(1)\)CF746GNewRoads构造一棵\(n\)个点的深度为\(t\)的树,以\(1\)为根,使其中深度为\(i\)的点有\(a_i\)个且叶节点有\(k\)个。或报告无解。\(t,k\len\le2\times10^5\)。为了方便,我们令根节点的深度为\(1\)。所有读入都向后顺延一位。......
  • 24/05/07 图论
    \(\color{green}(1)\)CF711DDirectedRoads有\(n\)个点和\(n\)条边,第\(i\)条边从\(i\)连到\(a_i\)(保证\(i\nea_i\))。每条边需要指定一个方向(无向边变为有向边)。问有多少种指定方向的方案使得图中不出现环,答案对\(10^9+7\)取模。\(n\le2\times10^5\)......
  • 好题——图论
    前言本文章将会持续更新,主要是一些个人觉得比较妙的题,主观性比较强(给自己记录用的),有讲错请补充。带!号的题是基础例题,带*号的是推荐首先完成的题(有一定启发性的)。图论最短路P1119灾后重建此题看到以后以为是很简单的最短路问题(实际也不难),就写了dijkstra,然后光荣的tie......
  • 24/04/27 图论及 dfs 序相关
    \(\color{green}(1)\)CF721CJourney给定一张\(n\)个点\(m\)条边的有向无环图,边有边权。构造一条\(1\ton\)的路径使得其边权和\(\lek\)且经过的点数最多。\(n,m\le5\times10^3\),\(k\le10^9\)。最简单的想法是设状态\(f_{i,j}\)表示\(1\toi\)的边权......
  • 24/04/25 图论
    \(\color{purple}(1)\)P5478[BJOI2015]骑士的旅行给定一颗\(n\)个节点的树。有\(m\)个骑士,最开始第\(i\)个骑士在\(p_i\)节点上,武力值为\(f_i\)。接下来有\(q\)次操作\((t_i,x_i,y_i)\):\(t_i=1\),输出树上\(x_i,y_i\)路径上的前\(k\)大骑士的武力值。......
  • (图论分析,思维)ABC 350-D
    背景:我自己思考想出来的图论题,总归是有成就感的分析:求间接连接的点的对数,即一个连通块中枚举出两两连接的组合数,减去整个连通块中的边数,因为一条边必然直接连接了两个不同的点原理:并查集时间复杂度:o(n)代码如下:点击查看代码#include<bits/stdc++.h>usingnamesp......
  • 【图论】最短路练习——P1629邮递员送信
    邮递员送信题目描述有一个邮递员要送东西,邮局在节点\(1\)。他总共要送\(n-1\)样东西,其目的地分别是节点\(2\)到节点\(n\)。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有\(m\)条道路。这个邮递员每次只能带一样东西,并且运送每件物品过后必须返回邮局。求送完......
  • 桥、割点和边双连通分量
    桥定义:删除后会增加联通块数量的边被称作桥。那么,如何求解呢?方法一首先跑出一颗dfs树。比如下图(\(2-6,1-5\)的边是非树边):可以发现,所有非树边和其构成的环上的所有边不可能是桥,因为删去后仍可以通过环的另一半。比如上图中只有\(1-2\)一个桥。那是不是除了这些边以外都是......
  • 图论理论基础
    Smiling&Weeping ----前方的风景好像很美...图论基础总结图论是研究图的结构和性质的数学分支。图是一种由节点(顶点)和边组成的数学结构,其中节点表示实体,边表示实体之间的关系。图论可以应用于解决许多现实世界中的问题,例如社交网络分析、交通......
  • [学习笔记] 树上差分 - 图论
    前置知识:树,LCA,前缀和与差分边差分这个名字是在网上看到的,不理解为什么要叫这么一个名字,可能是因为它与树链修改有关。当然,用于树链修改单点查询非常方便~看这个图,该图是以点1为根进行DFS的。如果我们要把从3->4这条树链上所有的点统统加上1,可以都转化为对到根节点的......