电子学会七级-数据结构-哈密顿路

电子学会七级-数据结构-哈密顿路
最短Hamilton路径
https://www.acwing.com/problem/content/93/

问题分析
假设:一共有七个点,用0,1,2,3,4,5,6来表示,那么先假设终点就是5,在这里我们再假设还没有走到5这个点,且走到的终点是4,那么有以下六种情况:
first: 0–>1–>2–>3–>4 距离:21
second: 0–>1–>3–>2–>4 距离:23
third: 0–>2–>1–>3–>4 距离:17
fourth: 0–>2–>3–>1–>4 距离:20
fifth: 0–>3–>1–>2–>4 距离:15
sixth: 0–>3–>2–>1–>4 距离:18

如果此时你是一个商人你会走怎样的路径?显而易见,会走第五种情况对吧?因为每段路程的终点都是4,且每种方案的可供选择的点是04,而商人寻求的是走到5这个点的最短距离,而4到5的走法只有一种,所以我们选择第五种方案,可寻找到走到5这个点儿之前,且终点是4的方案的最短距离,此时05的最短距离为(15+4走到5的距离).(假设4–>5=8)

同理:假设还没有走到5这个点儿,且走到的终点是3,那么有一下六种情况:
first: 0–>1–>2–>4–>3 距离:27
second: 0–>1–>4–>2–>3 距离:22
third: 0–>2–>1–>4–>3 距离:19
fourth: 0–>2–>4–>1–>3 距离:24
fifth: 0–>4–>1–>2–>3 距离:26
sixth: 0–>4–>2–>1–>3 距离:17

此时我们可以果断的做出决定:走第六种方案!!!,而此时0~5的最短距离为(17+3走到5的距离)(假设3–>5=5)

在以上两大类情况之后我们可以得出当走到5时:
1.以4为终点的情况的最短距离是:15+8=23;
2.以3为终点的情况的最短距离是:17+5=22;
经过深思熟虑之后,商人决定走以3为终点的最短距离,此时更新最短距离为:22。

当然以此类推还会有以1为终点和以2为终点的情况,此时我们可以进行以上操作不断更新到5这个点的最短距离,最终可以得到走到5这个点儿的最短距离,然后再返回最初的假设,再依次假设1,2,3,4是终点,最后再不断更新,最终可以得出我们想要的答案

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=20,M=1<<N;
//f[M][N]表示从0开始 经过的状态二进制 为M 到达点N 最短路径  
int f[M][N],w[N][N];//w表示的是无权图

int main(){
	int n;
	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;//因为零是起点,所以f[1][0]=0;
	
	for(int i=0;i<1<<n;i++)//i表示所有的情况
		for(int j=0;j<n;j++)//j表示走到哪一个点
			if(i>>j&1)//i右移j位 --i的第j位是否为1 --1&1=1 0&1=0
				for(int k=0;k<n;k++)//k表示走到j这个点之前,以k为终点的最短距离
					if(i>>k&1){//i的第k位是否为1 i-(1<<j) --i去除j的状态1101=14-(1<<2)=1001=9 
						//f[i-(1<<j)][k]+w[k][j] 通过k到j是否更短 
						f[i][j]=min(f[i][j],f[i-(1<<j)][k]+w[k][j]);//更新最短距离
					}
	cout<<f[(1<<n)-1][n-1]<<endl;//表示所有点都走过了,且终点是n-1的最短距离
	//位运算的优先级低于'+'-'所以有必要的情况下要打括号
	return 0;
}

posted @ 2022-06-01 12:39  new-code  阅读(33)  评论(0编辑  收藏  举报