数据结构:哈密顿回路基础

什么是哈密顿回路?

哈密顿回路(Hamiltonian Cycle)是图论中的一个概念,指的是在一个图中通过图的每个顶点恰好一次且仅一次,并最终回到起始顶点的闭合回路。在一个哈密顿回路中,除了起始和结束的顶点必须是同一个顶点,并且这个顶点恰好出现两次之外,其他每个顶点都恰好出现一次。哈密顿回路的命名来自于爱尔兰数学家威廉·罗伊兰·哈密顿。

判断是否存在哈密顿环问题是一个经典的NP完全问题,这意味着目前没有已知的多项式时间算法能解决所有情况。对于一个含有 V V V个顶点和 E E E条边的图来说,常见的算法时间复杂度如下:

  1. 暴力搜索法:尝试图中所有可能的顺序来查找哈密顿环。其时间复杂度为 O ( V ! ) O(V!) O(V!),因为需要检查每个顶点的所有排列。

  2. 回溯法:在搜索过程中,如果路径不满足条件,则回退一步。这是一种改进的暴力法,但最坏情况的时间复杂度仍然为 O ( V ! ) O(V!) O(V!)

  3. 动态规划(例如 Held-Karp 算法):用于求解旅行商问题(TSP),该问题与哈密顿环问题紧密相关。Held-Karp算法使用动态规划,其时间复杂度为 O ( V 2 2 V ) O(V^2 2^V) O(V22V)

  4. 启发式算法:如遗传算法、蒙特卡洛方法等,并不保证总是能找到解决方案,但在一些情况下它们可以在多项式时间内给出近似解。时间复杂度因算法和实现而异,但通常比 O ( V 2 2 V ) O(V^2 2^V) O(V22V)要低。

判断给路径是否是哈密顿回路

只需要满足条件:每个点经过一次,并且是一个环路就行。像判断是否是给定图的拓扑排序一样,按照流程走一遍就行。
优化代码:

  • 尽量不适用全局变量,使用引用传参。
  • 将条件合并。
#include <iostream>
#include <vector>
#include <unordered_set>

using namespace std;

bool isHamiltonianCycle(const vector<unordered_set<int>>& graph, const vector<int>& path) {
    if(path.front() != path.back() || path.size() != graph.size()) {
        return false;
    }
    
    unordered_set<int> visited;
    int len=path.size();
    for(int i = 0; i < len - 1; ++i) {
        if(graph[path[i]].count(path[i+1]) == 0 || visited.count(path[i]) != 0) {
            return false;
        }
        visited.insert(path[i]);
    }
    if(graph[path[len-2]].count(path.back()) != 0)
        return true;
    else return false;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cin >> N;
    vector<unordered_set<int>> graph(N + 1);

    cin >> M;
    while(M--) {
        int u, v;
        cin >> u >> v;
        graph[u].insert(v);
        graph[v].insert(u);
    }

    int K;
    cin >> K;
    while(K--) {
        int n, v;
        cin >> n;
        vector<int> path;
        path.reserve(n);//无所谓,这改变的是capacity,与resize不一样。
        
        while(n--) {
            cin >> v;
            path.emplace_back(v);
        }
        
        if(isHamiltonianCycle(graph, path)) {
            cout << "YES\n";
        } else {
            cout << "NO\n";
        }
    }
    return 0;
}

动态规划:最短哈密顿路径

最短哈密顿路径
该问题将在以后解释。

相关推荐

  1. 数据结构哈密回路基础

    2024-04-23 14:50:05       33 阅读
  2. Python计算物理粒子及拉格朗日和哈密动力学

    2024-04-23 14:50:05       38 阅读
  3. 数据结构-回溯算法

    2024-04-23 14:50:05       35 阅读
  4. LeetCode 447. 回旋镖的数量,枚举+哈哈

    2024-04-23 14:50:05       72 阅读
  5. 数据结构基础小结

    2024-04-23 14:50:05       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-23 14:50:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-23 14:50:05       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-23 14:50:05       82 阅读
  4. Python语言-面向对象

    2024-04-23 14:50:05       91 阅读

热门阅读

  1. 用户权限—— u+s\g+s\o+t三个特殊权限说明

    2024-04-23 14:50:05       30 阅读
  2. [Unity]动态修改URP资源的相关参数

    2024-04-23 14:50:05       35 阅读
  3. 数组的排序算法

    2024-04-23 14:50:05       23 阅读
  4. (二).数值进制&进制转换

    2024-04-23 14:50:05       38 阅读
  5. 【华为OD机试】5G网络建设【C卷|200分】

    2024-04-23 14:50:05       26 阅读
  6. Python和R热释光动能朗伯W函数解析方程

    2024-04-23 14:50:05       33 阅读
  7. 2.微服务技术

    2024-04-23 14:50:05       26 阅读
  8. 关于电脑卡死如何开机、F8、安全模式

    2024-04-23 14:50:05       33 阅读