首页 > 其他分享 >无向图的连通性(割点与割边)

无向图的连通性(割点与割边)

时间:2024-07-15 11:55:30浏览次数:11  
标签:连通性 int 无向 割点 dfn low root 节点

割点与割边


 

割点的求解方法


 

 

割点详解


 

板题: https://www.luogu.com.cn/problem/P3388     第1题     割点 查看测评数据信息

给出一个n个点,m条边的无向图,求图的割点。

输入格式

 

第一行输入两个正整数 n,m。

下面m行每行输入两个正整数x,y表示x到y有一条边。

对于全部数据,1≤n≤2×1e4,1≤m≤1×1e5。

点的编号均大于0小于等于n。

 

 

输出格式

 

第一行输出割点个数。

第二行按照节点编号从小到大输出节点,用空格隔开。

 

输入/输出例子1

输入:

6 7

1 2

1 3

1 4

2 5

3 5

4 5

5 6

 

输出:

5

 

样例解释

#include <bits/stdc++.h>
using namespace std;
const int N=2e4+5;

int n, m, u1, v1, dfn[N], low[N], idx=0, ans=0, root=0;
bool cut[N];
vector<int> a[N];
void dfs(int u, int fa)
{
	dfn[u]=low[u]=++idx;
	int child=0;
	
	for (int i=0; i<a[u].size(); i++)
	{
		int v=a[u][i];
		if (!dfn[v])
		{
			child++;
			dfs(v, u);
			
			low[u]=min(low[u], low[v]);
			
			if (low[v]>=dfn[u] && u!=root) cut[u]=1;
		}
		else
		{
			low[u]=min(low[u], dfn[v]); //*
		}
	}
	
	if (u==root && child>=2) cut[root]=1;
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=m; i++)
	{
		scanf("%d%d", &u1, &v1);
		a[u1].push_back(v1);
		a[v1].push_back(u1);
	}
	
	for (int i=1; i<=n; i++)
		if (!dfn[i])
		{
			root=i;
			dfs(i, 0);
		}
	
	for (int i=1; i<=n; i++)
		if (cut[i]) ans++;
	
	printf("%d\n", ans);
	for (int i=1; i<=n; i++)
		if (cut[i]) printf("%d ", i);
	
	return 0;
}

  

 

 

dfn[i] 表示 进入i节点时的时刻
low[i] 表示 以i节点往上走能够到达的时刻最小值

cut[i] 表示 第i个点是否为割点

然后不断dfs,更新low,时间戳比自身小才更新low值

 

判断割点条件:
1. low[v]>=dfn[u] 且 u!=1
(不可能走到u上面)

要特判根节点
2.根节点儿子>=2

 

 

 

#include <bits/stdc++.h>
using namespace std;
const int N=2e4+5;

int n, m, u1, v1, dfn[N], low[N], idx=0, ans=0, root=0;
bool cut[N];
vector<int> a[N];
void dfs(int u, int fa)
{
	dfn[u]=low[u]=++idx; //更新时间戳,最远跳到的时间戳初始化为自身 
	int child=0;  //该节点孩子数量 
	
	for (int i=0; i<a[u].size(); i++)
	{
		int v=a[u][i];
		if (!dfn[v]) //没有被访问过,确保了等下修改的low值是比自身时间戳要小的
		{
			child++; 
			dfs(v, u);
			//注意,这里要先往下dfs,之后才能更新值 
			//这样才能让下面的语句生效,从儿子的low值反过来更新父亲的low值
			//由于儿子能走到的最远距离(儿子多走了一段 u->v),父亲肯定也能走到
			low[u]=min(low[u], low[v]);
			
			//解释1 
			if (low[v]>=dfn[u] && u!=root) cut[u]=1;
		}
		else
		{
			//解释2 
			low[u]=min(low[u], dfn[v]);
		}
	}
	
	//解释3 
	if (u==root && child>=2) cut[root]=1;
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=m; i++)
	{
		scanf("%d%d", &u1, &v1);
		a[u1].push_back(v1);
		a[v1].push_back(u1);
	}
	//此题没规定一定联通,所以分别以每个点为根来找
	for (int i=1; i<=n; i++)
		if (!dfn[i])
		{
			root=i;
			dfs(i, 0);
		}
	
	for (int i=1; i<=n; i++)
		if (cut[i]) ans++;
	
	printf("%d\n", ans);
	for (int i=1; i<=n; i++)
		if (cut[i]) printf("%d ", i);
	
	return 0;
}

  

解释1+解释3:

low[v]>=dfn[u],即儿子走到的最远距离不超过父亲,那么这个时候隔断父亲,儿子也会跟着断。

反之亦然,如果儿子走过的最远距离超过父亲,就算隔断父亲,儿子还是能走过去

这种情况要注意是不是根节点

 

假设此时u为根节点,他的儿子是v,v的儿子有很多很多

此时儿子v最远跳到u,那么就满足了“low[v]>=dfn[u]”

那么u被认为是割点,但其实删去u,图还是连通的!

所以要此时要特判u不为根节点,此方法才生效。

 

那如何求x为根节点的情况?只需要看x的儿子是否>=2即可

也就是解释3

 

解释2:

 如果按照“low[u]=min(low[u], low[v])"来执行,4号点和5号点的low值都为1,那么这样判断下3号节点将不会是割点,事实上3号节点是一个割点。

所以要按照“low[u]=min(low[u], dfn[v])"来执行,确保3号节点能正常判断

 

 

 

例题:

https://www.luogu.com.cn/problem/P5058

第2题     嗅探器 查看测评数据信息

某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络。蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息。

但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可以不止有一条通路。

现在需要你尽快地解决这个问题,应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获?

输入格式

 

输入文件的第一行一个整数 n,表示蓝军网络中服务器的数目。

接下来若干行是对蓝军网络的拓扑结构描述,每行是两个整数i,j表示编号为i和编号为j的两台服务器间存在双向连接。

服务器的编号从1开始,一行两个0表示网络的拓扑结构描述结束,再接下来是两个整数a,b分别表示两个中心服务器的编号。

1≤n≤2×1e5,边数不超过 5×1e5

 

输出格式

 

输出满足条件的服务器编号。如果有多个解输出编号最小的一个,如果找不到任何解,输出 No solution。

 

输入/输出例子1

输入:

5

2 1

2 5

1 4

5 3

2 3

5 1

0 0

4 2

 

输出:

1

 

样例解释

 

割点好题。

 

标签:连通性,int,无向,割点,dfn,low,root,节点
From: https://www.cnblogs.com/didiao233/p/18302884

相关文章

  • 动态图连通性笔记
    首先离线的话有几种方法:线段树分治动态维护最大生成树:边的权值为他的(下一次)删除时间,加边正常做,询问时问路径最小值是否小于当前时刻.动态图连通性Holm-deLichtenberg-Thorup(HLT)暴力:维护生成森林,若删树边则暴力找另一条边能替代这条树边.思想:给每条边赋一个“不重......
  • 数据融合工具(6)线要素网络连通性分组计算
            出行,一直在使用导航辅助我们从起点奔赴终点,或许我们会有过这样的思考?导航路线规划是怎么实现的?        ……        我们先掰扯掰扯……一、导航路线规划是如何实现的?        导航路线规划是一种复杂的算法和技术,它用于确定......
  • 【复杂网络经典案例】无向和有向网络中心距离、效率及Delta中心性
    文章目录概要1.节点间的距离(Distance)2.节点间的效率3.Delta中心性4.仿真实现(JupyterNotebook)5.小结概要复杂网络理论涉及多种重要概念,包括无向和有向网络中的距离、效率和Delta中心性。这些概念有助于我们理解网络结构及其功能特性。1.节点间的距离(Distance)在网......
  • 无向图三元环计数
    DescriptionP1989无向图三元环计数给定简单无向图\(G=(V,E)\),求其三元环个数,其中\(\lvertV\rvert\leq10^5,\lvertE\rvert\leq2\times10^5\)。Solution考虑给每一个边定一个方向。具体地,对于原图的一条边\(E=(u,v)\),有若\(\deg_u>\deg_v\)或\(\text{deg}_u=\text{......
  • 连通性分析
    1、脑电连通指标1)基于相干的指标2)基于相位同步的指标3)基于广义同步的指标4)基于格兰杰因果的指标2、基于相干的指标1)相干指标的范围在0~12)局限性:仅能评估两个信号的线性依赖关系,不能检测他们之间的非线性关系;会受到信号波幅的影响;不能分离出容积求导对脑区间连通性的影响3)......
  • PCL 点云聚类(基于体素连通性)
    文章目录一、简介二、实现代码三、实现效果参考资料一、简介这里的思路很简单,我们通过将点云转换为体素,基于体素的连通性实现对点云的聚类(有点类似于欧式聚类),不过这种方式进行的聚类有些粗糙,但聚类速度相对会快很多,具体的实现效果可以详细阅读代码。二、实现......
  • Java实现管线拓扑关系连通性分析
    管线拓扑关系的连通性分析通常涉及图论(GraphTheory)中的概念,特别是无向图(UndirectedGraph)的遍历算法,如深度优先搜索(DFS,Depth-FirstSearch)或广度优先搜索(BFS,Breadth-FirstSearch)。在管线拓扑中,管线可以被视为图的边(Edge),而管线的连接点可以被视为图的节点(Vertex)。连通性分析......
  • 【无线传感器节点部署WSN】使用最陡下降法和遗传算法进行受连通性和覆盖范围约束的无
    ......
  • C++的算法:割点与割边
            在图论中,割点与割边是图的重要性质,它们在图的连通性、网络流等问题中扮演着关键角色。在C++中,我们可以通过深度优先搜索(DFS)等算法来判定一个图中的割点与割边。        割点,又称关节点或桥接点,是指在无向连通图中,如果删除某个顶点后,图的连通分量数增......
  • 知识点整理 - 连通性相关 | 《综述图论中连通性及相关问题的一些处理方法》学习笔记
    是ix35老师论文的学习笔记,同时也用作连通性相关知识梳理。可能不会包含很多定义,只会挑重要的写。会包含一些例题。定义与记号\(u\rightsquigarrowv\)代表\(u\)到\(v\)的一条路径。有时也会用这个记号表示连通性。无向图点/边连通度:若\(u,v\)任意点割集大小不小......