AcWing 91最短汉密尔顿路径
AcWing 91 最短Hamilton路径
题目描述
给定一个有n个点的加权无向图,
从0到n?1、求起点0到终点n?最短的汉密尔顿路径为1。
哈密尔顿路径定义为从0到n?1每一点恰好经过一次。
输入格式
在第一行输入整数n。
接下来,每行有n行n个整数,
其中第I行中的J整数表示从点I到J的距离(表示为[i,j])。
对于任何x,y,z,
确保数据a[x,x]=0
a[x,y]=a[y,x]
和a[x,y] a[y,z]a[x,z]
输出格式
输出一个整数,表示最短汉密尔顿路径的长度。
数据范围
1n20
0a[i,j]107
输入样例:
五
0 2 4 5 1
2 0 6 5 3
4 6 0 8 3
5 5 8 0 5
1 3 3 5 0
输出样例:
18
解题思路
根据问题的意思,每张图片中的每一点都需要经过一次。
所以我们可以用暴力的方法把——个数字排列完整。
数的全置换方法的时间复杂度\(O(n \次n!)\)
显然,这是行不通的。
再看下面的全排列。
\(1 2 3 4 .\)
\(1 3 2 4 .\)
可以发现,这两个完整的排列已经经历了1234的四个数字。
最后都是4号。
所以修剪可以在这里判断。
使用状态来压缩数组。
\(f[i][j]\)
其中I是一个二进制数。
指示图形的状态。
1表示通过,0表示未通过。
j表示最后一点落在哪里。
还需要列举J来自哪一点。
状态转移方程为:
$ f[i][j]=min(f[i][j],f[i\wedge 1j][k] w[k][j]) $
请注意,位操作的优先级高于逻辑异或操作。
解题代码
#包含iostream
#包括内存。h
使用命名空间标准;
const int N=21
int n,w[N][N],f[1N][N];
int main(){ 0
CIN;
for(int I=0;在;(一)
for(int j=0;jn;j)
CIN w[I][j];
memset(f,0x3F,sizeof(f));//初始数组都是无限的。
f[1][0]=0;//初始起点为0。
for(int I=1;i1n一)//枚举状态
for(int j=0;jn;J) if(ij1) //j必须通过。
for(int k=0;kn;k)如果((I ^ 1J)K1)//j不等于k,k则通过。
f[i][j]=min(f[i][j],f[i^1j][k]w[k][j]);//状态转移方程
cout f[(1n)-1][n-1];
}
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/103389.html