欧拉路和欧拉回路

11 篇文章 0 订阅
10 篇文章 1 订阅

欧拉路径的定义:

如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。
如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的图称为半欧拉图。

欧拉路径以及欧拉回路的判断:

奇点的定义:指跟这个点相连的边数目有奇数个的点。
定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。
定理2:存在欧拉回路的条件:图是连通的,有0个奇点。

为了更形象的了解这两个定理,请看下图:
在这里插入图片描述

这是一条欧拉路径,有且只有2个奇点,这里1和4是奇点,因为只有一条边和他们相连

在这里插入图片描述

这是一条欧拉回路,从起点开始最后还能回到起点,没有奇点,因为1,2,3,4没有一个点是奇数条边与它相连

欧拉路和欧拉回路的题目往往都会与深度优先搜索(DFS)关联,一笔画问题是欧拉路中的一道典型例题

一笔画问题

Description

如果一个图存在一笔画,则一笔画的路径叫做欧拉路,如果最后又回到起点,那这个路径叫做欧拉回路。

我们定义奇点是指跟这个点相连的边数目有奇数个的点。对于能够一笔画的图,我们有以下两个定理。

定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。

定理2:存在欧拉回路的条件:图是连通的,有0个奇点。

两个定理的正确性是显而易见的,既然每条边都要经过一次,那么对于欧拉路,除了起点和终点外,每个点如果进入了一次,显然一定要出去一次,显然是偶点。对于欧拉回路,每个点进入和出去次数一定都是相等的,显然没有奇点。

求欧拉路的算法很简单,使用深度优先遍历即可。

根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找欧拉路,则对一个奇点执行DFS,时间复杂度为O(m+n),m为边数,n是点数。

Input

第一行n,m,有n个点,m条边,以下m行描述每条边连接的两点。保证是一个连通的简单图,即两点之间没有多重边。1<=n, m<=1000。

Output

输出一个路径,按照字典序的最小序输出,用一个空格隔开,构成欧拉通路或欧拉回路。数据保证一定有通路或回路。

Sample Input 1

5 5
1 2
2 3
3 4
4 5
5 1

Sample Output 1

1 2 3 4 5 1

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e4+5;
int mp[maxn][maxn];
int d[maxn];		//记录每个点的度
int n,m;

vector<int>path;

void dfs(int x)		//深搜找路径
{
	for(int i = 1 ; i <= n ; i++)
	{
		if(mp[x][i])
		{
			mp[x][i] = mp[i][x] = 0;
			dfs(i);		
		}	
	}
	path.push_back(x);
}


int main()
{
	cin >> n >> m;
	for(int i = 1 ; i <= m ; i++)
	{
		int x,y;
		cin >> x >> y;
		mp[x][y] = mp[y][x] = 1;	//把可以连通的点标记为1
		d[x]++;
		d[y]++;
	}
	int st = 1;
	for(int i = 1 ; i <= n ; i++)
	{
		if(d[i] % 2 != 0)	//因为题目已经说过一定存在欧拉路或者欧拉回路所以只要找到一个奇点即可
		{
			st = i;
			break;
		}
	}
	dfs(st);
	int len = path.size();
	cout << path[len - 1];
	for(int i = len - 2 ; i >= 0 ; i--)//倒叙输出路径,因为在DFS中存路径实际上是一个递归的过程
	{
		cout << " " << path[i] ;
	}
	return 0;
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值