目录
一,哈密顿回路、哈密顿链路
图的哈密顿回路是指包含图的所有节点的回路。
图的哈密顿链路是指包含图的所有节点的链路。
二,相关定理
1,Dirac定理
如果G是一个n(n≥3)个点的无向简单图,所有节点的度数都 ≥ n/2.0,则G中存在哈密顿回路。
证明过程:
(1)G是连通图
(2)设最长路径是L,用抽屉原理可以证明L是个环
(3)如果有节点不在环中,根据连通性可以加入一个点把环变成一条更长的路径。所以所有节点都在这个环中。
2,Tutte定理
所有4连通平面图都有哈密顿圈。证明过程没研究。
关于平面图,参考常见的图
3,竞赛图必有哈密顿链路
关于竞赛图,参考常见的图

竞赛图中不存在环当且仅当所有顶点的出度从小到大排列依次为0, 1, 2, … , n-1 。
翻译成赛事语言就是,单循环赛结果没有环,当且仅当所有人的实力是线性排序的,没有任何一次比赛发生逆袭现象。
三,应用
1,旅行商问题(TSP)
给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。
这是NP难问题。
2,芯片通孔
芯片上有很多不同尺寸的通孔,用于走线。
同一尺寸的通孔用1个钻头全部打完之后,再换钻头。
对于1个钻头来说,如何走最短的距离把所有通孔打完?
四,求解哈密顿链路
哈密顿问题其实和TSP问题差不多,是NP问题,没有特别好的算法。
回溯法:
class Hamilton
{
public:
stack<int> hami;//哈密顿链路
Hamilton(int n, map<int, vector<int>>& m, int type)//type=0是无向图 1是有向图
{
this->n = n;
this->m = m;
this->type = type;
for (int i = 0; i < n; i++)dfs(i);
}
private:
bool dfs(int k)
{
s.push(k);
if (s.size() == n) {
hami = s;
return true;
}
for (auto nk : m[k]) {
if (visit[k])continue;
visit[k] = 1;
if (dfs(nk))return true;
visit[k] = 0;
}
s.pop();
return false;
}
int n;
int type;
map<int, vector<int>> m;//邻接表
map<int, int>visit;
stack<int>s;
};
力扣 996. 正方形数组的数目
给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。
返回 A 的正方形排列的数目。两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得 A1[i] != A2[i]。
示例 1:
输入:[1,17,8] 输出:2 解释: [1,8,17] 和 [17,8,1] 都是有效的排列。
示例 2:
输入:[2,2,2] 输出:1
提示:
1 <= A.length <= 120 <= A[i] <= 1e9
vector<int> gnums;
class Hamilton
{
public:
map<long long, int>ans;
Hamilton(int n, map<int, vector<int>>& m, int type)//type=0是无向图 1是有向图
{
this->n = n;
this->m = m;
this->type = type;
for (int i = 0; i < n; i++)dfs(i,1);
}
private:
bool dfs(int k,int deep)
{
if (visit[k])return false;
long long h2 = h;
hash(k);
if (hashVisit[h])
goto RET;
hashVisit[h] = 1;
if (deep == n) {
ans[h] = 1;
h = h2;
return true;
}
visit[k] = 1;
for (auto nk : m[k]) {
dfs(nk,deep+1);
}
RET:
v

博客围绕哈密顿回路和链路展开,介绍了Dirac定理、Tutte定理等相关定理,阐述了其在旅行商问题、芯片通孔等方面的应用。还提及求解哈密顿链路的回溯法,列举力扣相关题目,探讨了相关谜题、点的回路覆盖问题以及最短哈密顿链路的状态压缩DP解法。
最低0.47元/天 解锁文章
129

被折叠的 条评论
为什么被折叠?



