首页 > 其他分享 >连通性

连通性

时间:2024-12-30 20:55:15浏览次数:9  
标签:head 连通性 min int dfn maxn low

图论中的连通性相关的算法
(适合学过之后,总结复习的观看)
割边,割点,缩点

其实都有个共同的名字:tarjan

割边

对于一个连通的无向图,如果存在一条边,去除后,使其分为两个子图,无法连通,那么这个边可以称为割边

例题 炸铁路

对于一个访问过的点,且不是父节点\(low[u]=min(low[u],dfn[v])\)
对于一个未访问的点,\(low[u]=min(low[v],low[u])\)
判断割边的条件\(low[v]>dfn[u]\),则满足\((u,v)\)是一个割边

#include<bits/stdc++.h>

using namespace std;
int n,m;
const int maxn=1e4+10;
struct node {
	int v,next;
}e[maxn];
int head[maxn];
int cnt=0;
void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
vector<pair<int,int> >ans;
int tot=0;
int f[maxn]; 
int dfn[maxn],low[maxn];

void tarjan(int u,int fa){
	dfn[u]=low[u]=++tot;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		if(v!=fa && dfn[v])
			low[u]=min(low[u],dfn[v]);
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[v],low[u]);
			if(low[v]>dfn[u]) ans.push_back({min(u,v),max(u,v)}); 
		}
	}
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;++i){
		int a,b;cin>>a>>b;
		add(a,b);add(b,a);
	}
	for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i,i);
	sort(ans.begin(),ans.end());
	for(auto x:ans) cout<<x.first<<" "<<x.second<<endl;
	return 0;
} 

割点

例题 P3388 【模板】割点(割顶)

对于一个访问的点\(low[u]=min(low[u],dfn[v]);\)
对于一个未访问的点\(u!=fa,low[v]>=dfn[u]\),则u是割点
特别考虑开始遍历的根节点,如果有两颗以上的子树,则一定是割点

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;
int n,m;
const int maxn=1e5+10;
int head[maxn],low[maxn],dfn[maxn];
struct node{
	int v,next;
}e[maxn<<1];
bool book[maxn];
int cnt=0,tot=0;
void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int u,int fa){
	low[u]=dfn[u]=++tot;
	int child=0;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v,fa);
			low[u]=min(low[u],low[v]);
			if(u!=fa && low[v]>=dfn[u]) book[u]=1;
			if(u==fa) ++child;
		}
		else if(book[v])low[u]=min(low[u],dfn[v]);
	}
	if(u==fa && child>=2) book[u]=1;
}
int main(){
	cin>>n>>m;memset(book,0,sizeof(book));
 	for(int i=1;i<=m;++i){
		int u,v;cin>>u>>v;
		add(u,v);add(v,u); 
	}
	int js=0;
	for(int i=1;i<=n;++i) if(!dfn[i]) dfs(i,i);
	for(int i=1;i<=n;++i) if(book[i]) ++js;
	cout<<js<<endl;
	for(int i=1;i<=n;++i) if(book[i]) cout<<i<<" ";
	return 0; 	
}

缩点

对于一个有向图形成的环,我们可以将其压缩成一个点

P3387 【模板】缩点

缩点+拓扑排序

对于一个点,无论是否访问过,\(low[u]=min(low[u],low[v])\)

这里模板特别加上了拓扑排序,我们可以学会对缩点进行重新编号再操作

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

const int maxn=1e5+10;
int p[maxn];
int n,m;
int dfn[maxn],low[maxn];
int top=0;
bool vl[maxn];
int st[maxn],sd[maxn];
int sum=0,cnt=0;
int head[maxn*20];
struct node{
	int next,v,u; 
}e[maxn*20],a[maxn*20];
void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].u=u;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int u){
	low[u]=dfn[u]=++sum;
	st[++top]=u;vl[u]=1;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vl[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u]){//强连通分量的根节点 
		int x;
		while(x=st[top--]){
			sd[x]=u;//缩点 
			vl[x]=0;//使该点在之后不再能被访问
			if(x==u) break;
			p[u]+=p[x];
		}
	}
	return ;
}
void tarjan(){
	memset(vl,0,sizeof(vl));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	for(int i=1;i<=n;++i) 
		if(!dfn[i]) dfs(i);
}
int ct=0,r[maxn];
int h[maxn*20];
void topsort(){
	queue<int>q;
	int dis[maxn];
	memset(dis,0,sizeof(dis));
	for(int i=1;i<=n;++i)
		if(sd[i]==i && !r[i])
			q.push(i),dis[i]=p[i];
	while(!q.empty()){
		int k=q.front();q.pop();
		for(int i=h[k];i;i=a[i].next){
			int v=a[i].v;
			dis[v]=max(dis[v],dis[k]+p[v]);
			r[v]--;
			if(!r[v]) q.push(v); 
		} 
	}
	long long ans=0;
	for(int i=1;i<=n;++i)
		if(ans<dis[i]) ans=dis[i];
	cout<<ans<<endl;
	return ;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>p[i];
	for(int i=1;i<=m;++i){
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	tarjan();
	memset(h,0,sizeof(h));
	memset(r,0,sizeof(r));
	for(int i=1;i<=m;++i){
		int u=sd[e[i].u],v=sd[e[i].v];
		if(u!=v){
			a[++ct].next=h[u];
			a[ct].v=v;
			a[ct].u=u;
			h[u]=ct;
			++r[v];
		}
	}
	topsort();
	return 0;
} 

总结

我们通过这三个算法,可以进行一定的区分和寻找一定的相似的地方

区分

判定条件

割点 割边 缩点
\(low[u]\geq dfn[u]\) \(low[u]>dfn[u]\) \(low[u]= dfn[u]\)

访问点

割点 割边 缩点
访问过 \(low[u]=min(low[u],dfn[v])\) \(low[u]=min(low[u],dfn[v])\) \(low[u]=min(low[u],low[v])\)
未访问 \(low[u]=min(low[v],low[u])\) \(low[u]=min(low[v],low[u])\) \(low[u]=min(low[u],low[v])\)

这里应该是最不好理解的一点,我给出一种解释希望有所帮助:

low[u]表示的是节点u能够通过回边或子树到达的最小的节点编号

回边的存在:当我们在DFS中访问节点u的邻接节点v时,如果v已经被访问且在当前的递归栈中(即 in_stack[v] 为真),这意味着存在一条回边从 u到v。这条回边表明u可以通过v回到某个更早的节点。

dfn[v]是节点v被访问时的时间戳,表示v在DFS中的访问顺序。通过比较low[u]和dfn[v],我们可以确定u能够到达的最小节点编号。如果v的时间戳小于low[u],这意味着u可以通过v到达一个更早的节点,因此我们需要更新low[u]

相似点

都通过比较low和dfn的大小来确定是否存在割点,割边,缩边

标签:head,连通性,min,int,dfn,maxn,low
From: https://www.cnblogs.com/guiyou/p/18642171

相关文章

  • thcping6-用于检测网络节点之间的连通性。它支持多种高级功能
    thcping6作用:一个基于ICMPv6协议的ping工具,用于检测网络节点之间的连通性。它支持多种高级功能,如自定义ICMP消息、数据包速率控制等。主要用途:                       1、网络连通性测试:检测目标主机是否可达                     ......
  • 『联合省选2025集训』『图的连通性进阶』 知识点 总结
    前言若有长风绕旗,那便是我在想你了。这周讲了个图论连通性板块的一些进阶知识,周六全国第一给我们讲了一些树上的问题,感觉树剖板块实现难度较大,后面几道偏思维的题会有些许好转。这里就先写写连通性相关的进阶的一些知识点吧。主要涵盖:耳分解,双极定向,三连通分量和一些重要的......
  • 『联合省选2025集训』『图的连通性进阶』Day3 略解
    前言我们趋行在人生这个亘古的旅途,在坎河中奔跑,在挫折里涅槃,忧愁缠满全身,痛苦飘洒一地。我们累,却无从止歇;我们苦,却无法回避。今天是连通性的进阶题目,重点是耳分解,双极定向,以及边三连通分量。因为调题速度过慢,导致被硬控,所以第二天晚上补的差不多了再来写的。感觉知识点方面......
  • 连通性相关
    基础部分DFS生成树在有向图中,DFS生成树有\(4\)种边:树边:每次搜索找到一个还未访问过的节点时就形成了一条树边。返祖边:搜索时遇到在树上的祖先节点,指向祖先的边。横叉边:搜索时遇到已访问过的节点,但该节点不是当前节点的祖先,就形成了一条横叉边。前向边:搜索时遇到了子......
  • 端口连通性测试方法
    端口连通性测试方法一、telnettelnet<ip><port>说明:ip:是测试主机的ip地址port:是端口,比如22方法二、sshssh-v-pportusername@ip说明:-v调试模式(会打印日志)-p指定端口username:远程主机的登录用户ip:远程主机如果远程主机开通了相应的端口,会有如下图所示的......
  • 【唐叔学算法】第八天:并查集-图论连通性的大杀器
    你是否曾为如何高效地解决图论中的连通性问题而烦恼?并查集算法,就像一张无形的网,能帮你轻松连接所有节点。今天,就让我们一起揭开并查集算法的神秘面纱,探索它在Java编程中的应用。并查集是什么?并查集(Union-Find)是一种数据结构,用于处理一些不交集的合并及查询问题。它支持两......
  • 运维脚本:网络连通性测试
    1. 背景介绍在日常运维工作中,网络连通性是确保系统稳定性和高可用性的关键因素之一。通过测试网络连通性,运维人员可以快速诊断网络问题,判断系统与其他设备或服务的连接状态。这对于预防和处理网络故障至关重要。本文将介绍如何编写和使用一个简单的运维脚本,来自动化测试服务器......
  • Linux下端口连通性测试
    端口连通性测试使用nc命令Linux下自带/dev/tcp命令#!/bin/bash#检测脚本传入的参数if[$#-eq0];thenecho"使用格式:$0<IPPORT>|-f<file>"echo"<IPPORT>测试单个IP和端口"echo"-f<file>批量测试,使用参数-f指定要测试......
  • 图的连通性小记
    前言DFS树无向图DFS树定义:DFS树是在图或树结构上进行深度优先搜索时形成的树。在DFS过程中,从一个顶点开始,尽可能深地搜索图的分支,直到达到一个没有未访问邻居的顶点,然后回溯到上一个顶点继续搜索。从点\(r\)开始搜索,每次进入一个点\(i\)对应的边\((fa_i,i)\)为树......
  • WGCLOUD使用指南 - 监测数据库的连通性
    数据可视化监测是WGCLOUD的一个重要模块,可以帮我们监控数据源是否在线,自定义sql查询数据进行可视化展示,比如新增订单、注册用户量、数据库运行参数等信息数据监控是由server来监测的,因此要保证server主机能够访问到数据库如果server无法访问被监控的数据源,怎么监控 1、......