哈密顿回路、链路、其他点覆盖问题

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

目录

一,哈密顿回路、哈密顿链路

二,相关定理

1,Dirac定理

2,Tutte定理

3,竞赛图必有哈密顿链路

三,应用

1,旅行商问题(TSP)

2,芯片通孔

四,求解哈密顿链路

力扣 996. 正方形数组的数目

力扣 980. 不同路径 III

五,相关puzzle

1,数字满格、数阵迷踪、数字迷途、数字连线

2,踏马、立方骑士

3,矩形图中马的哈密顿回路、链路

六,点的回路覆盖问题

1,回路覆盖问题

2,相关定理

3,应用

七,最短哈密顿链路

1,模板

2,力扣 943. 最短超级串


一,哈密顿回路、哈密顿链路

图的哈密顿回路是指包含图的所有节点的回路。

图的哈密顿链路是指包含图的所有节点的链路。

二,相关定理

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. 1 <= A.length <= 12
  2. 0 <= 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值