【资料】Fluery's Algorithm( 用于查找Euler path 和Euler circuit)

Fleury's Algorithm 是一种用于找到图的欧拉路径和欧拉回路的算法。它是一个构造性的方法,通过选择起点,沿着未使用的边行走并标记已使用的边,遵循避免在减少图中跨越桥的原则,除非别无选择。此算法同样适用于欧拉路径。在执行算法前,应用欧拉定理检查图是否包含欧拉路径或回路。推荐题目供进一步练习。

复习discrete math 看了老师的课件感觉不靠普,在百度上也找不到好的科普贴,

只能从国外的网站上扒下来生肉,看英文贴还是挺舒服的= =

所以直接:点击打开链接

Introduction

  • Euler's Theorems are examples of existence theorems
  • existence theorems tell whether or not something exists (e.g. Eulercircuit)
  • but doesn't tell us how to create it!
  • we want a constructive method for finding Euler paths and circuits
  • methods (well-defined procedures, recipes) for construction are calledalgorithms
  • there is an algorithm for constructing an Euler circuit:  Fleury'salgorithm
  • we will illustrate it with the graph:
#include <iostream> #include <vector> #include <algorithm> using namespace std; vector<int> findEulerianPath(int n, vector<vector<int>>& graph) { vector<int> inDegree(n, 0), outDegree(n, 0); vector<vector<int>> adj(n); // 计算入度出度,并构建邻接表 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { outDegree[i] += graph[i][j]; inDegree[j] += graph[i][j]; for (int k = 0; k < graph[i][j]; k++) { adj[i].push_back(j); } } } // 检查是否存在欧拉路径或回路 int startNode = 0, endNode = 0; bool hasEulerPath = false, hasEulerCircuit = true; for (int i = 0; i < n; i++) { if (outDegree[i] != inDegree[i]) { hasEulerCircuit = false; if (outDegree[i] - inDegree[i] == 1) { startNode = i; hasEulerPath = true; } else if (inDegree[i] - outDegree[i] == 1) { endNode = i; } else { return {}; // 不存在欧拉路径 } } } if (!hasEulerPath && !hasEulerCircuit) { return {}; } // 确保字母顺序最小 for (auto& edges : adj) { sort(edges.begin(), edges.end()); } // Hierholzer算法找欧拉路径 vector<int> path; vector<int> stack; stack.push_back(hasEulerPath ? startNode : 0); while (!stack.empty()) { int u = stack.back(); if (!adj[u].empty()) { int v = adj[u].back(); adj[u].pop_back(); stack.push_back(v); } else { path.push_back(stack.back()); stack.pop_back(); } } reverse(path.begin(), path.end()); // 检查是否遍历了所有边 int totalEdges = 0; for (int i = 0; i < n; i++) { totalEdges += outDegree[i]; } if (path.size() != totalEdges + 1) { return {}; } return path; } int main() { int n; cin >> n; vector<vector<int>> graph(n, vector<int>(n)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> graph[i][j]; } } vector<int> path = findEulerianPath(n, graph); if (path.empty()) { cout << "Nothing found." << endl; } else { // 检查是否是回路 bool isCircuit = (path.front() == path.back()); if (isCircuit) { cout << "Euler circuit found:" << endl; } else { cout << "Euler path found:" << endl; } // 输出路径 for (int i = 0; i < path.size(); i++) { cout << char('a' + path[i]); if (i != path.size() - 1) { cout << " "; } } cout << endl; } return 0; }分析这段代码对于解决上面问题有什么错误或遗漏
最新发布
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值