最短Hamiton路径

题目链接: 91. 最短Hamilton路径 - AcWing题库

        题意: 给定一张n(n<=20)个点的带权无向图,点从0~n-1标号,求起点0到终点n-1的最短Hamilton路径。Hamilton路径的定义是从0~n-1不重不漏地经过每个点恰好一次。

        分析: 二进制状态压缩, 把每个点是否经过用一个二进制位标记,然后做dp。f[i][j]代表经过的点的状态对应的十进制数为i,这时经过的最后一个点为j, 那么第一维枚举从1到(1<<n)的所有状态,第二维枚举终点,第三维枚举中间状态。

        代码:

#include<bits/stdc++.h>
#define map unordered_map
#define all(v) v.begin(),v.end()
using namespace std;

typedef long long ll;

int n;
int mp[25][25];
int f[1 << 20][20];

void solve(){
	cin>>n;
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < n; j ++){
			cin>>mp[i][j];
		}
	}
	memset(f, 0x3f, sizeof f);
	f[1][0] = 0;
	for(int i = 1; i < 1 << n; i ++){
		for(int j = 0; j < n; j ++){
			if(i >> j & 1){ // j点已经走过
				for(int k = 0; k < n; k ++){
					if((i ^ 1 << j) >> k & 1){ // 还没走j点,但是已经走到了k点
						f[i][j] = min(f[i][j], f[i ^ 1 << j][k] + mp[k][j]);
					}
				}
			}
		}
	}
	cout<<f[(1 << n) - 1][n - 1]<<endl;
}

int main(){
	cin.tie(0) -> sync_with_stdio(false);
	//int t; cin>>t; while(t --)
		solve();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值