一、定义
1.基本概念
欧拉路径: 图G中的一条路径,能够通过图中的每一条边,并且每条边仅通过一次
欧拉回路: 就是闭合的欧拉路径
欧拉图: 包含欧拉回路的图
2.判断
有向图:
- 欧拉路径:有一个点出度比入度多1(起点),有一个点入度比出度多1(终点),其余点出度等于入度;
- 欧拉回路:每个顶点出度等于入度;
无向图:
- 欧拉路径:有且仅有两个点的入度为1,分别是起点和终点;
- 欧拉回路:图中所有顶点的度数都是偶数,并且该图是连通图;
二、例题
1.一笔画问题
问题描述:
如果一个图存在一笔画,则一笔画的路径叫做欧拉路,如果最后又回到起点,那这个路径叫做欧拉回路。
根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找欧拉路,则对一个奇点执行
d
f
s
dfs
dfs,时间复杂度为
O
(
m
+
n
)
O(m+n)
O(m+n),
m
m
m为边数,
n
n
n是点数。
输入
第一行
n
,
m
n,m
n,m,有
n
n
n个点,
m
m
m条边,以下
m
m
m行描述每条边连接的两点。
输出
欧拉路或欧拉回路,输出一条路径即可。
样例输入
5 5
1 2
2 3
3 4
4 5
5 1
样例输出
1 5 4 3 2 1
策略分析:
建图、存度数,然后dfs,同时记录路径即可代码
#include <iostream>
#define MAXN 10005
using namespace std;
bool g[MAXN][MAXN];
int n, m, ans[MAXN], dep[MAXN], cnt;
void dfs(int v) {
for(int i = 1; i <= n; i++) {
if(g[v][i]) {
g[v][i] = g[i][v] = 0;
dfs(i);
}
}
ans[++cnt] = v;
}
int main() {
ios::sync_with_stdio(0);
int u, v, s = -1;
cin >> n >> m;
for(int i = 1; i <= m; i++) {
cin >> u >> v;
g[u][v] = g[v][u] = 1;
dep[v]++, dep[u]++;
}
for(int i = 1; i <= n; i++) //找到起点
if(dep[i] % 2 == 1)
s = i;
if(s == -1) s = 1;
dfs(s);
for(int i = 1; i <= cnt; i++)
cout << ans[i] << " ";
return 0;
}