首页 > 其他分享 >图论

图论

时间:2023-10-08 15:26:40浏览次数:29  
标签:图论 int 路径 Dfs 回路 now 欧拉

图论这……感觉是知识点多,算法多,但用的频率不一定高,容易忘记,这里就整点板子防老年痴呆

欧拉路径

即一笔画问题,定义为:
图中经过所有边恰好一次的路径叫欧拉路径。如果此路径的起点和终点相同,则称其为一条欧拉回路

注意图必须连通,可用并查集或dfs判断

关于判断欧拉路径是否存在:

以下 \(S\) 为起点, \(T\) 为终点,并保证唯一

  • 有向图欧拉路径:\(S\) : 入度 + 1 = 出度; \(T\) : 入度 = 出度 + 1; 其余节点: 入度 = 出度
  • 有向图欧拉回路:所有节点: 入度 = 出度
  • 无向图欧拉路径:\(S, T\) : 度数为奇; 其余节点: 度数为偶
  • 无向图欧拉回路:所有节点: 度数为偶

在欧拉回路中,起点终点可以为任意点

关于求出欧拉回路

欧拉回路与欧拉路径(上)
欧拉回路与欧拉路径(下)
有向图:
从 \(S\) 开始跑dfs,每条边跑完后删去(打上标记),跑完所有儿子后再将该点入栈。
最后将整个栈反过来即为答案
关于正确性可画图感性理解

我是懒狗我不管

参考代码:

//N 为点的数量, M 为边的数量
int head[N], tot;
struct edge{
	int to, nxt;
	bool vis;
}e[M];
//有向边

int ans[M], cnt;
//每条边一次,共 M + 1 个点
//注意 M 开为数据范围 +5 即可

inline void Dfs(int now){
	for(int i = head[now]; i; i = e[i].nxt){
		if(!e[i].vis){
		//未访问过
			e[i].vis = 1;
			Dfs(e[i].to);
			//访问
		}
	}
	ans[++ cnt] = now;
	//入答案栈
}

一定注意最后答案是倒着入的栈,故需倒序输出

发现若用链式前向星存图,我们找未访问过的边时需将与该点相连的所有边都访问一次。
在这一操作上,其实使用领接链表更为便捷,以下为代码。

int num[N];//用法具体看Dfs函数
vector<int> to[N];
int ans[M], cnt;

inline void Dfs(int now){
	for(int i = num[now]; i < to[now].size(); i = num[now]){
	//以访问过的节点再也不会被访问啦
		num[now] ++;
		Dfs(to[now][i]);
	}
	ans[++ cnt] = now;
}

其实链式前向星应该也是支持这个操作的。只是

我是懒狗我不管

下面会提到如何实现

无向图:
类似于有向图的方法,只是删边时正边和反边一起删除罢了。

此时,若使用领接链表,会发现并不好处理删边,我们转回链式前向星。
实际上我们只是在找边时将查询的起始位置更新了,来避免多余的查询,将这思想放在链式前向星上,便是以下的代码。

int head[N], tot = 1;
//tot 从奇数开始方便查询反边
struct edge{
	int to, nxt;
	bool vis;
	//因为有未访问但被删除的反边存在,我们还是需要删除标记
}e[M << 1];
//无向图

int ans[M], cnt;

inline void Dfs(int now){
	for(int i = head[now]; i; i = head[now]){
		if(e[i].vis){
		//边已被删
			head[now] = e[i].nxt;
			continue;
		}
		e[i].vis = 1;
		e[i ^ 1].vis = 1;
		//删边
		head[now] = e[i].nxt;
		Dfs(e[i].to);
		
		ans[++ cnt] = now;
		//此句放循环外或内还并不清楚,有知道的麻烦留言提醒,谢谢了
	}
}
貌似欧拉回路题挺少的说

标签:图论,int,路径,Dfs,回路,now,欧拉
From: https://www.cnblogs.com/biuld/p/17748550.html

相关文章

  • MATLAB图论工具箱(哪有什么工具箱,就只是一堆函数而已)
    MATLAB图论工具箱图论基础Matlab图论工具箱提供了构建、操作和分析图形的函数和工具。在Matlab图论工具箱中,可以使用以下基本数据结构:graph:无向图。digraph:有向图。可以使用以下函数创建一个图或有向图:graph:创建一个无向图。digraph:创建一个有向图。%创建无......
  • 图论总结
    最小生成树相关次小生成树、生成树边替代对于一条非树边\((u,v)\),它替代树\(u,v\)链上的最大值,对答案的影响最小。用倍增或树链剖分维护。对于一条树边,如果非树边\((u,v)\)满足这条边在链\(u,v\)上,它被满足这个条件的权值最小的边替代对答案的影响最小。把非树边按权值......
  • 【图论】【寻找性质】CF1151E Number of Components 题解
    CF1151E发现每一个\(f(l,r)\)中的连通块总是一条链(一棵树)。那么此时连通块的数量就等于点的数量减去边的数量。先考虑点的总数,一个价值为\(a_i\)的点一定是在\(l\leqslanta_i\)且\(r\geqslanta_i\)的\(f(l,r)\)中才会有一个贡献,根据乘法原理,它会产生\(a_i\time......
  • [图论]判环的几种方法
    判环的几种方法拓扑排序判环对于有向图://有向图环判断#include<bits/stdc++.h>usingnamespacestd;vector<int>edge[10001];intn,m,d[10001];queue<int>q;inlinevoidTopoSort(){ intcnt=0; for(inti=1;i<=n;i++) { if(!d[i]) { q.push(i); ......
  • 算法刷题:图论(9.23,持续更)
    目录基础知识有向图顶点类邻接表邻接矩阵入度、出度有向加权图无向图(双向图)图的遍历题目DAG所有可能的路径判断二分图dfs解法bfs解法基础知识点:顶点、邻接节点边:有向边、无向边、加权边度:入度、出度、无向边的度环:环、自环(glist[i]中有i)连通性:连通图、不连通有向图顶点......
  • 【UVA 11175】From D to E and Back 题解(图论)
    取具有n个顶点和m条边的任意有向图D。你可以在以下方式。E将有m个顶点,每个顶点对应于D的每条边。例如,如果D有一条边uv,那么E将有一个叫做uv的顶点。现在,每当D有边uv和vw时,E就会有边顶点uv到顶点vw。E中没有其他边。你将得到一张E图,并且必须确定E是否有可能是某些有向图D的图的卧......
  • codeforces图论合集
    CyclicOperations给定一个数组$a$,每次构造一个数组$\spacel\space$长度为$\spacek\space$,数组$\spacea\space$与$\spacel\space$转换关系如下:$a_{l_1}\tol_2\space,\spacea_{l_2}\tol_3\space,\spacea_{l_3}\tol_4\space,\space...\space,\spacea_{l_n}\tol_1$......
  • 图论模板
    floyd算法template<typenameT>structFloyd{constTINF=std::is_same_v<T,longlong>?1e18:1e9;intn;std::vector<std::vector<T>>dp;Floyd(intn_):n(n_){dp.resize(n+1);for(auto&row:dp){......
  • 数学建模-图论
    写在前面在学习数据结构的图论时,有一类问题是很容易在现实生活中找到对应情况的问题,即最小路径问题,而对于其他的问题算法,如最小生成树等,我常常会困惑于其会应用于何种实际情况的求解,后面脱离了算法学习之后,这个问题算是搁置了下来。在接触到数学建模之后,我逐渐理解到为什么要在数......
  • 图论合集
    最短路算法全源最短路问题给出一张图\(G\),询问任意两点之间的最短路径。Floyd算法我们令\(f_{k,i,j}\)为只能经过\(1\simk\)的节点的最短路。那么初始化\(f_{0,i,j}\)为两点之间边权或者极大值。容易得到\(f_{k,i,j}=\min(f_{k,i,j},f_{k-1,i,x}+f_{k-1,x,j})\)......