AcWing 91. 最短Hamilton路径(状态压缩DP+哈密顿回路)

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 91. 最短Hamilton路径(状态压缩DP+哈密顿回路)相关的知识,希望对你有一定的参考价值。

题目链接

https://www.acwing.com/problem/content/description/93/

思路

这道题看似像一个最短路,但是并不是,因为我们要求对于每一个点都经过,但是最短路不能保证,所以我们换一个思路用DP,我们定义 f [ i ] [ j ] f[i][j] f[i][j]表示从0走到j,走过的所有点是i状态的最短路径,其中的i我们将其看为二进制表示,对于每一位我们用1表示这一个点走过,用0表示这一个点没走过,那么我们要经过第一个点是0,所以我们初始化 f [ 1 ] [ 0 ] = 0 f[1][0] = 0 f[1][0]=0表示走到0这个点花费的路径价值为0,然后假设倒数第二个点为 k k k那么我们要求的其实就是 s − > k − > j s->k->j s>k>j的一个路径最小值,对于 k − > j k->j k>j的路径我们已经固定了即 w [ k ] [ j ] w[k][j] w[k][j],那么从 s − > k s->k s>k的一个距离最短值就需要从前面的状态转移过来即: f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i − ( 1 < < j ) ] [ k ] + w [ k ] [ j ] ) f[i][j]=min(f[i][j],f[i-(1<<j)][k] + w[k][j]) f[i][j]=min(f[i][j],f[i(1<<j)][k]+w[k][j]),最后 f [ ( 1 < < n ) − 1 ] [ n − 1 ] f[(1<<n)-1][n-1] f[(1<<n)1][n1]就是从 0 0 0走到 n − 1 n-1 n1且将所有点都走过(因为状态都标成1了)的最短路径值

代码

#include<bits/stdc++.h>
using namespace std;

const int N = 21;
int w[N][N],f[1<<N][N];
int n;

int main()

	cin>>n;
	for(int i = 0;i < n; ++i) 
		for(int j = 0;j < n; ++j)
			cin>>w[i][j];
	
	memset(f,0x3f,sizeof f);
	f[1][0] = 0;
	for(int i = 0,l = (1<<n);i < l; ++i)
		for(int j = 0;j < n; ++j) 
			if(i & (1 << j))
				for(int k = 0;k < n; ++k) 
					if(i & (1 << k))
						f[i][j] = min(f[i][j],f[i-(1<<j)][k] + w[k][j]);
	
	cout<<f[(1<<n)-1][n-1]<<endl;
	
	return 0;

以上是关于AcWing 91. 最短Hamilton路径(状态压缩DP+哈密顿回路)的主要内容,如果未能解决你的问题,请参考以下文章

《算法竞赛进阶指南》-AcWing-91. 最短Hamilton路径-题解

Acwing-91-最短Hamilton路径(状压DP)

AcWing 91. 最短Hamilton路径

91. 最短Hamilton路径状压DP

AcWing91 最短Hamilton路径 (状压dp)

ybtoj 状压DP课堂过关AcWing 91最短 Hamilton 路径 &例题2最短路径