首页 > 编程语言 >欧拉路径与Hierholzer算法

欧拉路径与Hierholzer算法

时间:2022-10-19 11:01:54浏览次数:50  
标签:一个点 奇数 int 路径 算法 回路 Hierholzer 欧拉

欧拉路径:如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。

欧拉回路:如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的图称为半欧拉图。

欧拉路径存在的条件:

1. 图为无向连通图
2. 奇数点为2个或0个,其余点度数为偶数(两个奇数点即为起点和终点)。

证明:
我们要使每个边恰好经过一次,那么对于每个中间点,必然从一条入边到达这个点再从一条出边离开这个点那么入边数必然等与出边数,换句话说只要到达一个点必然要有一条边离开这个点。

1.当奇数点个数大于2时,必然有不能完全遍历每一条边。
2.当奇数点为0个时,说明每个点都能成功到达并离开,那此图就构成了欧拉回路,我们必然可以从一个点出发最后再回到这个点。

Hierholzer算法

我们记录每个点的度数,以便于找到起点和终点,当奇数点为2时,选择其中一个点作为起点,另一个点为终点,当奇数点为0时,随机找一个点作为起点,此时图构成欧拉回路,当奇数点不为0或2时,欧拉路不存在。
我们使用DFS遍历每一条边,每走过一条边,就将他删去,保证每条边只经过一次。
我们使用栈来存储路径,以便于最后倒序输出。

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

int n;
int g[N][N];
int deg[N];

int odd[N];
int even[N];
int cnt;
stack<int>st;
int maxn;

void Hierholzer(int x)
{
	for(int i=1;i<=maxn;i++)
	{
		if(g[x][i])
		{
			g[x][i]--;
			g[i][x]--;
			Hierholzer(i);
		}
	}
	st.push(x);
}

int main(){
	
	cin>>n;
	int c=550;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		g[x][y]++;
		g[y][x]++;
		c=min(c,x);
		c=min(c,y);
		deg[x]++;
		deg[y]++;
		maxn=max(maxn,max(x,y));
	}
	
	for(int i=1;i<=maxn;i++)
	{
		if(deg[i]&1) odd[++cnt]=i;
	}
	if(cnt!=2&&cnt)
	{
		printf("No solution!");
		return 0;
	}
	int start;
	if(cnt) start=min(odd[1],odd[2]);
	else start=c;
	
	Hierholzer(start);
	
	while(st.size())
	{
		printf("%d\n",st.top());
		st.pop();
	}
	
	return 0;
}

标签:一个点,奇数,int,路径,算法,回路,Hierholzer,欧拉
From: https://www.cnblogs.com/mrkou/p/16805475.html

相关文章

  • 粒子群优化算法-Python版本和Matlab函数调用
    前两天分享了粒子群优化算法的原理和Matlab原理实现,本文分享一下Python代码下的PSO实现以及Matlab下的粒子群函数。前文参看:​​粒子群优化算法(PSO)​​以Ras函数(Rastrigin's......
  • 算法复杂度,本机1s用例测试
    本机配置:MacBookPro2019CPU:2.4GHz四核IntelCorei5第一个用例:时间复杂度O(n)//O(n)voidfunction1(longlongn){longlongk=0;for(longlong......
  • 代码随想录算法训练营第七天 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之
    做完题目,总算理解为什么三数之和荣获“初代噩梦”的称号了。真的是对照着题解才能弄明白每一步到底都想干些什么……454.四数相加II从四个数组里各挑一个元素,只考察组合......
  • 06 数组与广义表 | 数据结构与算法
    1.数组1.数组的定义数组:数组是一组偶对(下标值,数据元素值)的集合。在数组中,对于一组有意义的下标,都存在一个与其对应的值。一维数组对应着一个下标值,二维数组对应着......
  • Dubbo——时间轮(Time Wheel)算法应用
    定时任务Netty、Quartz、Kafka以及Linux都有定时任务功能。 JDK自带的java.util.Timer和DelayedQueue可实现简单的定时任务,底层用的是堆,存取复杂度都是O(nlog(......
  • Problem P34. [算法课分支限界法]硬币问题
    根据题目可以联想到无限个数物品的背包问题,dp[j]表示能组合为j的个数是多少,外层i循环是遍历表示加入第i个数之后的状态,因为是无限个数,所以内层循环是正序遍历,加了......
  • vue源码分析-diff算法核心原理
    这一节,依然是深入剖析Vue源码系列,上几节内容介绍了VirtualDOM是Vue在渲染机制上做的优化,而渲染的核心在于数据变化时,如何高效的更新节点,这就是diff算法。由于源码中关于d......
  • 数据结构——————排序算法代码实现(未完待续......)
    排序算法插入排序折半插入排序希尔排序冒泡排序快速排序简单选择排序堆排序归并排序(未完成)基数排序(未完成)#include<bits/stdc++.h>usingnamespacestd;constintMAXN......
  • 51Nod 1088 最长回文子串——————Manacher,马拉车算法
    ​​51Nod1088最长回文子串​​基准时间限制:1秒空间限制:131072KB分值:0难度:基础题回文串是指这种左右对称的字符串。输入一个字符串,输出里最长回文子串的长度。I......
  • 算法测试-定义算法模型评测标准
    测试方案将产品方期望转化为约束条件约定通过测试的标准:一定数据的算法结果中能满足约束条件的最低比例准备测试数据,统计计算结果能达到各项约束条件的比例示例具......