返回

C++ 最长环算法:深入浅出剖析和实现

后端

在计算机科学领域,寻找图中环的长度有着重要的应用价值。本文将深入剖析 C++ 中最长环算法,从题目到实现细节,逐层深入,带你领略算法之美。

题目

给定一个无向图,找到图中长度最长的环。

题目整理

  • 输入:无向图,由邻接表表示
  • 输出:图中长度最长的环的长度

解题思路

寻找最长环是一个 NP 难题。算法流程如下:

  1. DFS 预处理: 进行深度优先搜索(DFS),记录每个节点的访问顺序。
  2. 构建逆邻接表: 根据 DFS 顺序,构建逆邻接表,其中每个节点存储其访问顺序较小的节点。
  3. 寻找候选环: 从每个节点出发,进行深度搜索,记录形成的环。
  4. 计算环长: 遍历每个候选环,计算其长度,选择最长的环。

实现细节

#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;
    }
};

结语

掌握图论算法是计算机科学的重要组成部分。最长环算法是一个经典问题,通过深入分析问题,我们可以设计出高效的算法并将其转化为代码。希望本文能帮助你更好地理解算法的精髓,提升你的代码能力。