返回
C++ 最长环算法:深入浅出剖析和实现
后端
2023-11-27 00:09:14
在计算机科学领域,寻找图中环的长度有着重要的应用价值。本文将深入剖析 C++ 中最长环算法,从题目到实现细节,逐层深入,带你领略算法之美。
题目
给定一个无向图,找到图中长度最长的环。
题目整理
- 输入:无向图,由邻接表表示
- 输出:图中长度最长的环的长度
解题思路
寻找最长环是一个 NP 难题。算法流程如下:
- DFS 预处理: 进行深度优先搜索(DFS),记录每个节点的访问顺序。
- 构建逆邻接表: 根据 DFS 顺序,构建逆邻接表,其中每个节点存储其访问顺序较小的节点。
- 寻找候选环: 从每个节点出发,进行深度搜索,记录形成的环。
- 计算环长: 遍历每个候选环,计算其长度,选择最长的环。
实现细节
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
int findLongestCycle(const vector<vector<int>>& graph) {
int n = graph.size();
vector<int> order(n);
int idx = 0;
dfs(1, -1, order, idx, graph);
vector<unordered_map<int, int>> reverse_adj(n);
for (int i = 1; i < n; i++) {
for (int next : graph[i]) {
if (order[i] > order[next]) {
reverse_adj[i][next] = order[next];
}
}
}
int longest_cycle = 0;
for (int i = 1; i < n; i++) {
int cycle = dfs_find_cycle(i, -1, reverse_adj, order);
longest_cycle = max(longest_cycle, cycle);
}
return longest_cycle;
}
private:
void dfs(int node, int parent, vector<int>& order, int& idx, const vector<vector<int>>& graph) {
order[node] = ++idx;
for (int next : graph[node]) {
if (next == parent) continue;
if (order[next] == 0) {
dfs(next, node, order, idx, graph);
}
}
}
int dfs_find_cycle(int node, int parent, const vector<unordered_map<int, int>>& reverse_adj, const vector<int>& order) {
if (reverse_adj[node].count(parent)) {
return order[node] - reverse_adj[node][parent] + 1;
}
int max_cycle = 0;
for (const auto& [next, next_order] : reverse_adj[node]) {
if (next == parent) continue;
max_cycle = max(max_cycle, dfs_find_cycle(next, node, reverse_adj, order));
}
return max_cycle;
}
};
结语
掌握图论算法是计算机科学的重要组成部分。最长环算法是一个经典问题,通过深入分析问题,我们可以设计出高效的算法并将其转化为代码。希望本文能帮助你更好地理解算法的精髓,提升你的代码能力。