B3610 [图论与代数结构 801] 无向图的块 题解

这篇具有很好参考价值的文章主要介绍了B3610 [图论与代数结构 801] 无向图的块 题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

B3610 [图论与代数结构 801] 无向图的块 题解

2023 2023 2023,再见。 2024 2024 2024,你好!

解法

其实就是统计点双连通分量的个数。需要注意的是,孤立点在这里不被看作块。本文使用 tarjan 算法来解决这道题。

概念明晰

  • 时间戳:这里记为 d f n i dfn_i dfni,表示第一次深度优先搜索到节点 i i i 的时间。时间 t i m e ∈ N + time \in \mathbb{N}^+ timeN+ 且随这搜索依次递增。
  • 搜索树:从选定的节点出发的深搜,每个节点仅搜索一次,把所有搜索路径组成一颗树,称为搜索树。如果给定的图不是一整个连通图,则称为搜索森林。
  • 追溯值:这里记为 l o w i low_i lowi,表示节点 i i i 最多经过一条返祖边能走到搜索树中以 i i i 的子树中的节点的最小 d f n dfn dfn 为多少(简洁的定义出自东灯的博客)。
  • 割点:对于一个无向图,如果把一个点删除后这个图的极大连通分量数增加了,那么这个点就是这个图的割点。

追溯值的计算

首先根据定义, l o w i low_i lowi 的初始值应赋为 d f n i dfn_i dfni。现在考虑怎么进一步更新 l o w i low_i lowi

  • 如果在搜索树上 i i i j j j 的父节点,则 l o w i = min ⁡ ( l o w i , l o w j ) low_i = \min(low_i,low_j) lowi=min(lowi,lowj)
  • 如果从 i i i j j j 的连边不是搜索树上的边,则 l o w i = min ⁡ ( l o w i , d f n j ) low_i= \min(low_i,dfn_j) lowi=min(lowi,dfnj)

割点的判定方法

定义搜索树中节点 i i i 的子树为 s o n i son_i soni

  • 如果 i i i 不是搜索树的根,则当 ∃ d f n i ≤ l o w j , j ∈ s o n i \exists dfn_i \le low_j,j \in son_i dfnilowj,jsoni 时, i i i 是割点。
  • 如果 i i i 是搜索树的根,则当有两个不同的 j j j 满足上述条件时, i i i 是割点。

判定方法的证明

如果 d f n i ≤ l o w j dfn_i \le low_j dfnilowj,则证明从 j ∈ s o n i j \in son_i jsoni 出发,不经过点 i i i 无论如何也不能到达 i i i 的祖先。所以如果把 i i i 删去,则 s o n i son_i soni 就会与原图分离。文章来源地址https://www.toymoban.com/news/detail-776607.html

代码

#include<bits/stdc++.h>
using namespace std;
#define Getchar() p1==p2 and (p2=(p1=Inf)+fread(Inf,1,1<<7,stdin),p1==p2)?EOF:*p1++
#define Putchar(c) p3==p4 and (fwrite(Ouf,1,1<<7,stdout),p3=Ouf),*p3++=c
char Inf[1<<7],Ouf[1<<7],*p1,*p2,*p3=Ouf,*p4=Ouf+(1<<7);
inline void read(int &x,char c=Getchar())
{
	bool f=c!='-';
	x=0;
	while(c<48 or c>57) c=Getchar(),f&=c!='-';
	while(c>=48 and c<=57) x=(x<<3)+(x<<1)+(c^48),c=Getchar();
	x=f?x:-x;
}
inline void write(int x)
{
	if(x<0) Putchar('-'),x=-x;
	if(x>=10) write(x/10),x%=10;
	Putchar(x^48);
}
struct my_stack
{
	int top,a[500010];
	inline int size()
	{
		return top;
	}
	inline int &operator[](const int &x)
	{
		return a[x];
	}
	inline int back()
	{
		return a[top];
	}
	inline void push_back(const int &x)
	{
		a[++top]=x;
	}
	inline void pop_back()
	{
		top--;
	}
	inline void clear()
	{
		top=0;
	}
};
my_stack v;
int n,m,head[500010],cnt,dfn[500010],low[500010],times,belong[500010],tot;
vector<int> ans[500010];
struct edge
{
	int to,next;
};
edge e[4000010];
inline void add(const int &x,const int &y) noexcept
{
	e[++cnt].to=y,e[cnt].next=head[x],head[x]=cnt;
}
inline void tarjan(const int &pos,const int &fa)
{
	int son=0;
	dfn[pos]=low[pos]=++times,v.push_back(pos);
	for(int i=head[pos];i;i=e[i].next)
		if(!dfn[e[i].to])
		{
			son++,tarjan(e[i].to,pos),low[pos]=min(low[pos],low[e[i].to]);
			if(low[e[i].to]>=dfn[pos])
			{
				tot++;
				while(v[v.top+1]!=e[i].to) ans[tot].push_back(v.back()),v.pop_back();
				ans[tot].push_back(pos);
			}
		}else if(e[i].to!=fa) low[pos]=min(low[pos],dfn[e[i].to]);
}
int main()
{
	read(n),read(m);
	for(int i=1,x,y;i<=m;i++) read(x),read(y),add(x,y),add(y,x);
	for(int i=1;i<=n;i++) if(!dfn[i]) v.clear(),tarjan(i,0);
	for(int i=1;i<=tot;i++) std::sort(ans[i].begin(),ans[i].end());
	std::sort(ans+1,ans+tot+1,[](std::vector<int> &lhs,std::vector<int> &rhs)
	{
		for(int i=0;i<std::min(lhs.size(),rhs.size());i++) if(lhs[i]!=rhs[i]) return lhs[i]<rhs[i];
		return lhs.size()<rhs.size();
	});
	write(tot),Putchar('\n');
	for(int i=1;i<=tot;i++,Putchar('\n'))
	{
		for(int j=0;j<ans[i].size();j++) write(ans[i][j]),Putchar(' ');
	}
	fwrite(Ouf,1,p3-Ouf,stdout),fflush(stdout);
	return 0;
}

到了这里,关于B3610 [图论与代数结构 801] 无向图的块 题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第三章 图论 No.10无向图的双连通分量

    无向图有两种双连通分量 边双连通分量,e-DCC 点双连通分量,v-DCC 桥:删除这条无向边后,图变得不连通,这条边被称为桥 边双连通分量:极大的不含有桥的连通区域,说明无论删除e-DCC中的哪条边,e-DCC依旧连通 (该连通分量的任意边属于原图中的某条环)。此外,任意两

    2024年02月12日
    浏览(29)
  • 数据结构:有向完全图和无向完全图的边数

    一个拥有n个结点的无向完全图的边数为:n×(n−1)÷2 具体的解释: 比如我们有一个拥有4个结点的无向完全图, 我们首尾依次连接,共有4条边。 然后我们选择其他的两条边来连线。 又多出了2条边。一共有4 + 2 = 6条边。 我们来分析一下具体的过程,首先如果为n个结点的话,

    2024年02月11日
    浏览(34)
  • 【数据结构】无向图的最小生成树(Prime,Kruskal算法)

    连通图 :在 无向图 中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中 任意一对顶点都是连通的 ,则称此图为连通图 强连通图 :在 有向图 中,若在每一对顶点vi和vj之间都存在一条从vi到vj的路径,也存在一条从vj到vi的路径,则称此图是强连通图 生成

    2024年01月24日
    浏览(36)
  • C++数据结构之图的存储结构——邻接矩阵和邻接表实现无向图

    关键点: 1.构建二维数组 2.对应边的位置赋值为1 由于比较简单就直接上代码: 个人对邻接表实现无向图的理解如下,仅供参考:         由于无向图的组成是由多个顶点和多条无向边组成的,因此我们可以把它拆分成两个结构,分别是顶点和无向边,又由于我们是使用

    2024年02月05日
    浏览(43)
  • 数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

      图采用邻接表存储结构,编程实现图的深度优先搜索和广度优先搜索算法。              2.1创建图 2.1.1定义图的顶点、边及类定义   我们定义一个 邻接表类(ALGraph) 。这里实现一些基础的数据结构。要注意结构体的嵌套。    Edge: 用于表示图中的边

    2024年02月04日
    浏览(42)
  • 数据结构几种常见图的邻接矩阵的画法(有向图带权值,有向图不带权值,无向图带权值,无向图不带权值)

    这不马上要期末考试了,复习的时候突然发现了有好几种图的邻接矩阵需要画,在网上找了半天结果发现也没有特别详细的总结,所以经过总结写一下吧,希望对有需要的人,有点帮助吧!!!!(如有不对还请见谅!!!!!~~~~~~) 1,有向图带权值   2.有向图不带权值

    2024年02月13日
    浏览(41)
  • 图论-图的基本概念与数据结构

    无向图 边是没有方向的,也就是双向的 结点 V = { v 1 , v 2 , . . . , v 7 } mathcal{V} = { v_1,v_2,...,v_7} V = { v 1 ​ , v 2 ​ , ... , v 7 ​ } 边 ε = { e 1 , 2 , e 1 , 3 , . . . , e 6 , 7 } varepsilon = {e_{1,2},e_{1,3},...,e_{6,7}} ε = { e 1 , 2 ​ , e 1 , 3 ​ , ... , e 6 , 7 ​ } 图 G = { V , ε } mathcal{G} = { math

    2024年02月08日
    浏览(38)
  • 代数结构与图论

    图的阶:图中的顶点数 ,n 个顶点被称为 n 阶图 零图:一条边都没有 平凡图:一阶零图 基图:将有向图的各条有向边改成无向边所得到的无向图称为该有向图的基图 关联次数:可能取值为0,1,2 (分别是边与顶点没有关联,vi !=vj , 环) 孤立点:图中没有边关联的顶点 区

    2024年02月03日
    浏览(27)
  • 图论与算法(1)图论概念

    在计算机科学中,图论与算法是两个重要且紧密相关的领域。图论研究图的性质和特征,而算法设计和分析解决问题的方法和步骤。图论提供了一种形式化的方法来描述和分析各种关系和连接,而算法则为解决图相关的问题提供了有效的解决方案。 图论是研究图的结构和性质

    2024年02月07日
    浏览(30)
  • 图论与网络优化

    CSDN 有字数限制,因此笔记分别发布,目前: 【笔记1】概念与计算、树及其算法 【笔记2】容量网络模型、遍历性及其算法 【笔记3】独立集及其算法 2.1.1 定义 图(graph) G G G 是一个有序的三元组,记作 G = V ( G ) , E ( G ) , ψ ( G ) G=V(G),E(G),psi (G) G = V ( G ) , E ( G ) , ψ ( G ) 。 V (

    2024年02月06日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包