使用 DFS寻找欧拉路的基本思想如下:(拆边思想)
1、DFS 寻找到第一个无边可走的结点,则这个结点必定为终点。由于是 dfs递归结束的时候记录的,那么该边是走完欧拉道路的最后的那条边,层层返回之后最开始的也是最开始的出发的地方。
2、接下来由于 DFS 的递归回溯,会退回终点的上一个结点,继续往下搜索,直到寻找到第二个无边可走的结点,则这个结点必定为欧拉路中终点前最后访问的结点。
3、当通过 DFS遍历完整张图后,就可以倒序储存下整个欧拉路。
防止死循环的方法:
走过的边拆掉
#include <bits/stdc++.h>
using namespace std;
int a[30][30]; //邻接矩阵
int n, e;
int d[30]; //存储每个结点的度
int r[50]; //存储走过的点
int k = 0; //表示数组长度
//从x深搜
void dfs(int x) {
//讨论 x可能去的点
for (int i = 1; i <= n; i++) {
//如果 xi 之间有边
if (a[x][i] == 1) {
//拆边
a[x][i] = 0;
a[i][x] = 0;
dfs(i);
}
}
//回溯时,记录路径
k++;
r[k] = x;
}
int main() {
cin >> n >> e;
int x, y;
//读入e条边
for (int i = 1; i <= e; i++) {
cin >> x >> y;
a[x][y] = 1;
a[y][x] = 1;
//统计结点的度
d[x]++;
d[y]++;
}
//求起点:默认为 1,求最大的奇点
int s = 1;
for (int i = n; i >= 1; i--) {
if (d[i] % 2 == 1) {
s = i;
break;
}
}
dfs(s); //从 s 开始搜索
//逆序打印欧拉路或者欧拉回路
for (int i = k; i >= 1; i--) {
cout << r[i] << " ";
}
return 0;
}
题目练习:
https://hlcoding.com/solution/description/2272/
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com