上一篇
在图论算法中,欧拉路径(Euler Path)和欧拉回路(Euler Circuit)是非常经典的问题。它们不仅具有理论意义,还在实际应用中如电路设计、DNA测序等领域有重要用途。本文将用通俗易懂的方式,教你如何使用C++语言判断一个图是否存在欧拉路径或欧拉回路,并输出具体的路径。
注意:我们讨论的是无向图的情况(有向图也可类似处理,但判断条件不同)。

要判断一个连通无向图是否存在欧拉路径或欧拉回路,只需检查每个顶点的度数(连接的边数):
一旦确认图存在欧拉路径/回路,我们可以使用 Hierholzer 算法 来构造具体路径。该算法的核心思想是:
下面是一个完整的 C++ 实现,支持判断并输出欧拉路径或回路:
#include <iostream>#include <vector>#include <stack>#include <algorithm>using namespace std;// 判断图是否连通(使用 DFS)bool isConnected(const vector<vector<int>>& graph, int n) { vector<bool> visited(n, false); stack<int> st; // 找到第一个有边的顶点作为起点 int start = -1; for (int i = 0; i < n; ++i) { if (!graph[i].empty()) { start = i; break; } } if (start == -1) return true; // 空图视为连通 st.push(start); visited[start] = true; while (!st.empty()) { int u = st.top(); st.pop(); for (int v : graph[u]) { if (!visited[v]) { visited[v] = true; st.push(v); } } } // 检查所有有边的顶点是否都被访问 for (int i = 0; i < n; ++i) { if (!graph[i].empty() && !visited[i]) return false; } return true;}// Hierholzer 算法求欧拉路径vector<int> findEulerPath(vector<vector<int>>& graph, int n) { // 计算每个顶点的度数 vector<int> degree(n, 0); for (int i = 0; i < n; ++i) { degree[i] = graph[i].size(); } // 检查连通性 if (!isConnected(graph, n)) { return {}; // 不连通,无欧拉路径 } // 统计奇度顶点 vector<int> oddVertices; for (int i = 0; i < n; ++i) { if (degree[i] % 2 == 1) oddVertices.push_back(i); } // 判断是否存在欧拉路径 if (oddVertices.size() != 0 && oddVertices.size() != 2) { return {}; // 既不是回路也不是路径 } // 确定起点 int start = 0; if (!oddVertices.empty()) { start = oddVertices[0]; } else { // 找任意一个有边的点作为起点(用于欧拉回路) for (int i = 0; i < n; ++i) { if (!graph[i].empty()) { start = i; break; } } } // 使用栈进行 Hierholzer 算法 stack<int> currPath; vector<int> eulerPath; currPath.push(start); while (!currPath.empty()) { int u = currPath.top(); // 如果还有未访问的边 if (!graph[u].empty()) { int v = graph[u].back(); graph[u].pop_back(); // 从邻接表中移除反向边(无向图) auto it = find(graph[v].begin(), graph[v].end(), u); if (it != graph[v].end()) { graph[v].erase(it); } currPath.push(v); } else { eulerPath.push_back(u); currPath.pop(); } } return eulerPath;}int main() { // 示例:5个顶点的图 int n = 5; vector<vector<int>> graph(n); // 添加边(无向图) graph[0].push_back(1); graph[1].push_back(0); graph[1].push_back(2); graph[2].push_back(1); graph[2].push_back(3); graph[3].push_back(2); graph[3].push_back(4); graph[4].push_back(3); graph[4].push_back(1); graph[1].push_back(4); vector<int> path = findEulerPath(graph, n); if (path.empty()) { cout << "该图不存在欧拉路径或欧拉回路。" << endl; } else { cout << "欧拉路径为:"; for (int i = path.size() - 1; i >= 0; --i) { cout << path[i]; if (i > 0) cout << " -> "; } cout << endl; } return 0;}
isConnected 函数用于判断图是否连通(欧拉路径存在的前提)。findEulerPath 函数先检查度数条件,再用 Hierholzer 算法构建路径。通过本教程,你已经掌握了如何用 C++算法 实现欧拉路径和欧拉回路的判断与构造。关键在于理解图的度数性质和 Hierholzer 算法的递归思想。这类图论算法是算法竞赛和工程实践中的重要工具,建议多加练习!
如果你觉得这篇文章对你有帮助,欢迎分享给更多学习 C++语言 和算法的朋友!
本文由主机测评网于2025-12-19发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20251210080.html