割边和割点

网易笔试题-求有向连通图的割点 首先,明白割点定义:如果去除此点,则有向图不再连通。割点的具体情况可以结合下面的图来分析: 可以看到,割点有两种情况(通过深度优先搜索树来遍历): 1.如果是根节点,且有大于或等于两个以上的子树,则为割点。 2.如果不是叶节点的某节点node(比如节点J,K是叶子节点,但他们不属于割点),对于node来说它的子结点及后继结点没有指向node的祖先的回边,则为割点。譬如图中的E结点,它 阅读详情

图论基础算法之割边割点,没想到为了调整各种细节还花了我不少时间

无向图中的tarjan

算法说明

图论算法没有图很难说明,在此只做最简单的叙述就好

首先对于一张图进行DFS,由DFS过程引入三个概念:

  • 时间截:节点进行DFS的时间顺序编号
  • 搜索树:深搜路径的生成树
  • 追溯值:一个节点不通过父节点能够到达其他节点的最早时间截

分别用dfs[n]dfs[n]dfs[n]、low[n]low[n]low[n]表示时间截和追溯值

很容易可以想象出,如果:

  • 存在一个节点的子节点满足:
    dfs[pos]<=low[child]dfs[pos]<=low[child]dfs[pos]<=low[child]
    则说明有至少一个由子节点构成的连通块除了通过搜索树,没有其他路径回到树的根节点
    所以该点删除后必然产生一个独立的连通块,此时该点为割点

    tips:当pos为根节点时,需要存在两个child节点满足条件才可判断根节点为割点

  • 存在一条边满足:
    dfs[pos]<low[child]dfs[pos]<low[child]dfs[pos]<low[child]
    则说明通过该边的子节点的子搜索树中没有其他能通往根节点的路径
    删掉该边后产生新的连通块,所以此边为割边

代码实现

原理很好理解,但是在代码实现和做题过程中,我遇到了不少的问题,接下来对犯过的错误和需要注意的点进行记录

luogu模板题

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <utility>

using namespace std;

struct Edge
{
    int from;
    int to;
    int next;
} ed[200005];

int head[20005];
int low[20005];
int dfs[20005];
bool isAns[20005];
int num;

int n, m;
int org = 1;

int sum[20005];

int ans = 0;

void add(int f, int t)
{
    ed[++num].from = f;
    ed[num].to = t;
    ed[num].next = head[f];
    head[f] = num;
}

int times = 0;
bool flag_1 = 0;
void tarjan(int pos)
{
    dfs[pos] = low[pos] = ++times;

    for (int i = head[pos]; i; i = ed[i].next)
    {
        int y = ed[i].to;

        if (dfs[y])
        {
            low[pos] = min(low[pos], dfs[y]);
            continue;          //当搜索树到达边界后,不能继续搜索下去,也不能
                               //对叶节点进行统计
        }
        else
        {
            tarjan(y);
            low[pos] = min(low[pos], low[y]);
        }
        if (low[y] >= dfs[pos])
        {
            if (pos == org)
            {
                if (flag_1 == 0)
                {
                    flag_1 = 1;
                }
                else if (flag_1 == 1 && isAns[pos] == 0)//已经确认的点不能再统计一次答案
                                             //否则会重复增加ans的数量
                {
                    isAns[pos] = 1;
                    ans++;
                }
            }
            else if (isAns[pos] == 0)
            {
                isAns[pos] = 1;
                ans++;
            }
        }
    }
}

int main()
{
    cin >> n >> m;

    for (int i = 1; i <= m; i++)
    {
        int u, v;
        cin >> u >> v;
        add(u, v);
        add(v, u);
    }
    for (int i = 1; i <= n; i++)//题目中的图不一定联通,对于每个点都要检查
    {
        if (dfs[i] == 0)
        {
            flag_1 = 0;
            times = 0;
            org = i;//每次确定了连通块后,需要修改根节点和flag
            tarjan(i);
        }
    }
    cout << ans << endl;
    for (int i = 1; i <= n; i++)
    {
        if (isAns[i])
        {
            cout << i << ' ';
        }
    }
}

注释中记录的四个关键点确实让我浪费了不少时间调试找错

双连通分量

当一个图中不存在割边或割点时,我们称其为边双连通图或点双连通图

满足条件的子图我们称之为分量

边双连通分量求法

只需要求出所有割边,删去割边后剩下的就是边双连通分量

e-DCC缩点

把所有e-DCC作为节点,割边作为边,可以产生一棵树

点双连通分量的求法

维护一个栈,每遇到一个新的节点就入栈
最后判断节点是否为割点时,如果是割点,则出栈直到该节点出栈,所有出栈节点构成点双连通分量

然后可以进行缩点:

v-DDC缩点

割点可能同时被多个点双连通分量包括,所以v-DDC缩点的策略是把割点作为一个节点,然后每个点双连通分量作为一个节点和割点相连

有向图中的Tarjan

有向图中选取一个根节点可以到达其他所有点,,我们称之为流图

在有向图中讨论割边割点是一个很别扭的事情,我鲜有看见相关的文章
相对应的,在有向图中更常见到的是强连通分量——任意两个点可以自由通达的最大强连通子图(分量包括的含义就是最大连通的子图)

有向图中的Tarjan类似于无向图,也是一个最小追溯值的一个计算
dfs的过程中维护一个栈
计算出最小追溯值后,如果low[pos]==dfn[pos]low[pos]==dfn[pos]low[pos]==dfn[pos],则一直出栈直到pos出栈为止,所有出栈的节点构成一个环,即为一个强连通分量

Luogu P3387 缩点

#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>

using namespace std;

struct Edge
{
    int from;
    int to;
};

deque<Edge> head[10001];

int degree[10001];
deque<Edge> head_new[10001];
int node_w_new[10001];
int map[10001];
int cnt = 0;

void add(int f, int t)
{
    head[f].push_back(Edge{f, t});
}

stack<int> node;
int node_w[10001];

int dfn[10005];
int low[10005];
bool inTheStack[10001];
int count = 0;
void tarjan(int p)
{
    count++;
    node.push(p);
    dfn[p] = count;
    low[p] = count;
    inTheStack[p] = 1;
    for (const auto &el : head[p])
    {
        int y = el.to;
        if (dfn[y] && inTheStack[y])//y must be in the stack
        {
            low[p] = min(low[p], dfn[y]);
        }
        else if (!dfn[y])
        {
            tarjan(y);
            low[p] = min(low[p], low[y]);
        }
    }
    if (low[p] == dfn[p])
    {
        ++cnt;
        while (node.top() != p)
        {
            int temp = node.top();
            node.pop();

            inTheStack[temp] = 0;

            node_w_new[cnt] += node_w[temp];//add up the weight
            map[temp] = cnt;//map to its belonging
        }
        int temp = node.top();
        node.pop();

        inTheStack[temp] = 0;

        node_w_new[cnt] += node_w[temp];
        map[temp] = cnt;
    }
}

int cal(int p)
{
    int ans = 0;

    for (const auto &el : head_new[p])
    {

        ans = max(ans, cal(el.to));
    }
    return ans + node_w_new[p];
}

int main()
{
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= n; i++)
    {
        map[i] = i;
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> node_w[i];
    }

    int f, t;
    for (int i = 1; i <= m; i++)
    {
        cin >> f >> t;
        add(f, t);
    }

    for (int i = 1; i <= n; i++)
    {
        if (!dfn[i])
            tarjan(i);
    }
    // cout << inTheStack[2]<< endl;
    for (int i = 1; i <= n; i++)
    {
        for (const auto &el : head[i])
        {
            if (map[el.from] == map[el.to])
            {
                continue;
            }

            head_new[map[el.from]].push_back(Edge{map[el.from], map[el.to]});
            //this is such an amazing way to deal with each edge

            degree[map[el.to]]++;
        }
    }
    int ans = 0;
    for (int i = 1; i <= cnt; i++)
    {
        if (!degree[i])
        {
            ans = max(ans, cal(i));
        }
    }
    cout << ans << endl;
}
  • 将每个节点在缩点后的新图中建立映射关系,然后就可以直接更新每一条边在新图中的对应链接,非常巧妙的方式
PyTorch深度学习实战(24)——使用U-Net架构进行图像分割 图像分割 (Image segmentation) 是计算机视觉领域中的一个重要任务,旨在将图像划分为具有语义信息的不同区域或对象。与目标检测任务不同,图像分割要求像素级别的精确定位和分类,将每个像素标记为属于哪个类别或属于哪个区域。在本节中,我们将介绍图像分割的基本概念,并训练一个基于 U-Net 架构的图像分割模型。 阅读详情

相关推荐

macOS 27下PlayCover“没有权限打开”的完整修复指南

macOS系统通过Gatekeeper、TCC(透明、同意与控制)和安全启动等机制,对第三方应用进行层层校验,以防范恶意代码。这些机制会检查应用的隔离属性、签名状态以及所需系统权限,当任一环节不满足时,就会出现“没有权限打开”的提示。对于开发者工具或未上架App Store的开源软件,这类拦截尤为常见。尤其在macOS 27上,系统进一步收紧了绕过策略,导致PlayCover等工具无法正常启动。本文以PlayCover为例,详细解析权限链路上的三道关卡,并给出清除隔离属性、调整SIP状态、重置TCC记录等完

weixin_32612263的博客 740

有向图的割点问题

求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通,描述算法。 ----------------------------------------- 图的割点问题,深度优先遍历,如果某点的所有子孙节点与其祖先节点之间没有相连的边。 From : http://sokoban.ws/blog/?p=1000

taoqick的专栏 3630

SAP系统中PP模块全配置文档

配置路径IMG>SAP NetWeaver>常规设置>维护日历>工厂日历事务代码SCAL要求传输工厂代码描述日历代码日历描述起始日期星期一星期二星期三星期四星期五星期六星期日有效开始日期有效结束日期1000南微医学工厂MT南微医学工厂日历√√√√√√√201820502.4定义工厂配置路径IMG>生产>物料清单>常规数据>定义BOM状态事务代码OS23要求传输配置路径IMG>生产>主数据>资源>常规数据>标准值>定义参数。

yanzibing99的博客 1892

Tarjan 之 有向图(强连通分量)、无向图(割点/点双、割边/边双) (板子总结)

思路来源 https://www.cnblogs.com/nullzx/p/7968110.html(比较清晰的tarjan图示) https://blog.youkuaiyun.com/STILLxjy/article/details/70176689(比较清晰的C++板子) https://www.cnblogs.com/letlifestop/p/10262951.html(割点代码参考) ht...

小衣同学的博客 1226

【3D计算机视觉】从PointNet到PointNet++理论及pytorch代码

从PointNet到PointNet++理论及代码详解1. 点云是什么1.1 三维数据的表现形式1.2 为什么使用点云1.3 点云上以往的相关工作2. PointNet2.1 基于点云的置换不变性2.1.1 由对称函数到PointNet(vanilla)2.1.2 理论证明2.2 基于点云的旋转不变性2.3 网络总体结构2.4 实验结果和网络的鲁棒性2.5 代码解析3. PointNet++3.1...

小执着的博客 8万+

蓝桥杯嵌入式(基础教程)STM32G431RBT6——创建工程以及点灯

首先选择正确的芯片类型:STM32G431RBT6工程的创建主要有配置时钟以及烧录的方式。在配置好之后需要对时钟进行配置,由于蓝桥杯的外部晶振是24MHz因此需要对时钟树进行相应的配置。第一步先点击时钟配置之后就可以对时钟进行相应的配置了最后一步,需要对工程起一个名字,并且要选择KEIL做为其相应的软件之后再需要再生成代码那里进行相应的控制。当然这样根据生成的工程不能直接使用会有一个报错,所以需要添加一个启动文件。这个启动文件可以在官方的LCD文件夹下复制到自己的工程中。

m0_74051113的博客 1093

39 求一个有向连通图的割点

/* (2). 求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通,描述算法。 1. 最简单也是最直接的算法是,删除一个点然后判断连通性,如果删除此点,图不再连通, 则此点是割点,反之不是割点(图的连通性一般通过深搜来判定,是否能一次搜索完全部顶点); 2. 通过深搜优先生成树来判定。从任一点出发深度优先遍历得到优先生成树, 对于树中任一顶点V而言,其孩子节点

小人物的草稿本 1163

Oracle 11g版本下载及安装超详细教程图解

新手Oracle安装教程

weixin_43738344的博客 10万+

【图割】最大流最小切割的最直白解读

先看例子会好理解一点 什么是图? 本文针对的图主要是有向图,具体定义先不给出,先看一个具体例子: 图1:示例有向图 上图就是一个有向图,不用看官方定义,我们自己就能给出自己的定义: 1. 有向图包含了顶点与边; 2. 每一条边有两个端点,并且指明了两个端点之间的指向方向; 3. 每一条边有对应的值(具体含义与具体的模型化场景有关)。 以上定义虽然不是官方定义,但在本文中,这样的定义已经足够使用。为了更好的描述我们总结的定义,所以我给出一个形式化的有向图定义: 图2:有向图...

mjiansun的专栏 2840

手把手教你用XC7A35T FPGA搭建低成本机器视觉系统(含开发板选型指南)

本文详细介绍了如何利用AMD(原Xilinx)Artix-7系列中的XC7A35T FPGA芯片,搭建一套低成本的机器视觉系统。内容涵盖从芯片选型深度剖析、开发板(如黑金AX7035B)对比指南,到使用Vivado创建工程、编写图像处理模块(如RGB转灰度),以及资源优化和与上位机(如OpenCV)协同工作的完整流程,旨在为开发者提供一套可实践的高性价比硬件加速视觉解决方案。

beta5的博客 353

3.PCIe协议分析1-预备知识点

PCIE协议分析1主要讲一下四方面: PCI-E配置空间 PCI-E地址映射 PCI-E Bar空间 PCI-E层级结构详谈 (1)PCIE配置空间 我们过来学习PCIE的同学应该都接触各种类型的功能芯片吧,这些功能芯片连接在电路里面我们可以认为它是一个外部设备,这些设备里面有自己独有的寄存器区域,比如SDRAM里面的ID寄存器或者其他配置寄存器。好的,其实我们PCIE板卡也相当...

一个早起的程序员 4144

无向图的割点割边和双连通分量

无向图的割点、割边 Tarjan算法求无向图的割点 //啊哈算法 图的割点 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; const int N = 2e4 + 10; int n, m, root; b...

NaNa 652

【YOLOv11多模态融合改进】| CVPR2025 LCA轻量交叉注意力 双向模态交叉引导 + 双支路噪点抑制,兼顾纹理与热目标特征融合

可见光模态富含纹理、色彩、边缘细节,但夜间/低照度场景信噪比极低,暗区噪声泛滥;红外模态依靠热辐射凸显弱小目标、暗区物体轮廓,但缺失真实色彩与精细纹理。简单拼接/逐加融合仅做浅层特征叠加,无法建立可见光纹理、红外热特征的双向引导关联,两类模态互补信息无法精准互通;普通自注意力仅单模态内部建模,跨模态交互匮乏,红外热目标易被可见光暗噪声淹没,可见光有效纹理易被红外灰度信息覆盖;

Limiiiing的博客 115

求割边和割点

int low[MAX],dep[MAX],mark[MAX],cutpoint[MAX]; void dfs(int s,int father,int depth) { int u,v,tot=0; mark[s]=1; low[s]=dep[s]=depth; for(int i=0;i<mp[s].size();i++) { v=mp

IWBE的专栏 783

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

hihoCoder1183 tarjan算法应用之割边和割点

#include #include #include using namespace std; int n,m,order=0; int low[20004],dfn[20004],father[20004],son[20004]; //father:父结点 son:子结点个数 vector cutpoint,edge[20004]; vector > cutedge; void tarjan

Free Loop~~~跳动的音符 503

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

关于tarjan算法的一些理解(割边和割点)

首先介绍以下tarjan算法: ---------------------------------------------tarjan算法----------------------------------------------------------- tarjan算法思想: tarjan算法在离线求LCA,强连通分量,割边,割点,点双连通分量,边双连通分量很有用 tarjan算法中主

llin-黎辰 3413

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

割点、割边和双连通分量

[点连通度与边连通度]        在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合。一个图的点连通度的定义为,最小割点集合中的顶点数。       类似的,如果有一个边集合,删除这个边集合以后,原图变成多个连通块,就称这个点集为割边集合。一个图的边连通度的定义为,最小割边集合中的边数。

水题收集者 1321

割点割边判定 法则

割边判定法则; 无向边(u,v)(u,v)(u,v)是桥,当且仅当搜索树上存在uuu的一个子节点vvv满足:dfn[u]<low[v]。 如何理解这个式子: 桥是什么,桥是两个单独岛屿的桥。 什么是单独的岛屿,还记得桃花源记里面的世外桃源吗。 什么是世外桃源,就是与外人间隔。 再者,什么是追溯值,就是一个节点可以在自己子树和子树可以拓展的节点中找到一个最小的编号。 删掉了桥,那么在世外桃源...

nuoyanli的博客 4147

【算法模板】图论:Tarjan算法求割边割点

定义:特性:定义:特性:定义:性质:存在割点时必有割边:如果一个节点是割点,那么至少存在一条通过该节点的割边。删除割点会导致图分裂为多个部分,每个部分之间至少存在一条割边。割边连接的节点可能是割点:割边的两个端点节点至少有一个可能是割点。特别是在边的两个端点是不同的双连通分量时,这两个节点通常是割点。独立的关系:虽然割点和割边紧密相关,但它们也可以独立存在。一个图可以有割点而没有割边,或者有割边而没有割点。例如,星型图的中心节点是割点,但星型图的每条边都是割边。 例题 P3388 【模板】割点(割顶) 给出

2303_80346267的博客 2786

[模板]割點/割邊

tarjan最重要的之一應該就是dfn和low兩個數組吧,這裡判割邊和割點都是根據的這兩個數組 這裡的思路來自李煜東算法競賽進階指南,好像還有一些其他寫法,但是自己比較菜不會...... 注意這裡的寫法cnt(邊的編號)要初始化為1 一、割邊 對於割邊的判定,需要:   搜索樹上存在一個x的子節點y要滿足dfn[x]<low[y] 意思就是如果從x的子樹出發,...

weixin_30340775的博客 102

无向图的割边、割点

我们今天要来说一个新的东西:割边,割点。 显然,又有人要问了:什么是无向图的割边,割点??? 好,我们先来解决这个问题。 一、定义 割边:对于无向连通图来说,如果删除一条边之后使得这个图不连通,那么该边为割边 割点:对于无向连通图来说,如果删除一个点以及与它相连的边之后,那么该点为割点 二、割边割点的求法 1.割点的求法 对于一个点u, 1.u为dfs搜索树的根,如果搜索树中...

weixin_33711647的博客 931

POJ 1523 SPF 无向图求割点和块

来源:http://poj.org/problem?id=1523 题意:给一个无向图,求该无向图中的割点和该割点属于块的数量。一个割点是可以属于多个块的。 思路:深搜,dfs解决。给出一些无向图中关于割点割边的知识,是从网上找的。 一、基本概念 无向图 割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图。 块:没有割点的连通子图 割

2212

连通图的割点、割边(桥)、块、缩点,有向图的强连通分量

连通图的割点、割边(桥)、块、缩点,有向图的强连通分量   【本文摘选自百度文库】 一、基本概念 无向图 割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图。 块:没有割点的连通子图 割边:删掉一条边后,图必然会分裂成两个或两个以上的子图,又称桥。 缩点:把没有割边的连通子图缩为一个点,此时满足任意两点间都有两条路径相互可达。 求块跟求缩点非常相似,

Fighting! 5195

割点、割边模板(tarjan)

割边:牛客小白月赛12- I 代码如下: #include&lt;iostream&gt; #include&lt;cstdio&gt; #include&lt;algorithm&gt; #include&lt;string&gt; #include&lt;cstring&gt; #include&lt;queue&gt; #include&lt;stack&gt; #include&am

m0_37579232的博客 319

割点、割边、双连通分支

一、割点、割边、双连通分支概念 挂接点(Articulation point)就是割点(Cut Vertex) 桥(Bridge)就是割边(Cut Edge) 割点:v为割点,则去掉v后,图的连通分支增加。 割边:v为割边,则去掉v后,图的连通分支增加。 割点形式化的定义:a是割点当且仅当存在两个点u,v使得u到v的每条路径都会经过a。(去掉a后,u到v没有路径) 边双

xiazdong 5636

割点、割边

一、割点、割边、双连通分支概念 挂接点(Articulation point)就是割点(Cut Vertex) 桥(Bridge)就是割边(Cut Edge) 割点:v为割点,则去掉v后,图的连通分支增加。 割边:v为割边,则去掉v后,图的连通分支增加。 割点形式化的定义:a是割点当且仅当存在两个点u,v使得u到v的每条路径都会经过a。(去掉a后,u到v没有路径) 边双连通分支

u013638884的专栏 2906
上一篇: 平衡树初步——Treap
下一篇: 简单数据结构
尘_无下限
博客等级 码龄8年 74粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值