ybtoj 状压DP课堂过关AcWing 91最短 Hamilton 路径 &例题2最短路径
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ybtoj 状压DP课堂过关AcWing 91最短 Hamilton 路径 &例题2最短路径相关的知识,希望对你有一定的参考价值。
Link
ybtoj【状压DP课堂过关】【例题2】最短路径
AcWing 【91】最短 Hamilton 路径
题面//因为不知道侵不侵权所以就是题面是私密的,有账号的直接看转送门就可了
题目大意
给出n个点,和n个点之间边的长度
找出最短的一条路,遍布所有点(不能重复走)
解题思路
我爱状压!!!
之前在jz做过一个高阶版
所以这题做起来还挺顺的
设 f[i][j] 为遍布状态为 i,最后一个遍布的点是 j 的最短路径
f
[
i
]
[
j
]
=
m
i
n
(
f
[
i
]
[
j
]
,
f
[
i
x
o
r
(
1
<
<
j
−
1
)
]
[
k
]
+
s
[
k
]
[
j
]
)
f[i][j] = min(f[i][j], f[i\\ xor\\ (1 << j - 1)][k] + s[k][j])
f[i][j]=min(f[i][j],f[i xor (1<<j−1)][k]+s[k][j])
(基础状压真的太喜欢了)
Code
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, maxn;
int s[25][25], f[1050000][20];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) //本人不太喜欢0开始,所以就1 ~ n了
for(int j = 1; j <= n; j ++)
scanf("%d", &s[i][j]);
int maxn = (1 << n) - 1;
memset(f, 0x7f, sizeof(f));
f[1][1] = 0; //初始化,起点是1
for(int i = 2; i <= maxn; i ++) {
for(int j = 1; j <= n; j ++) {
if(!(i & (1 << j - 1))) continue; //i中必须遍布了j
for(int k = 1; k <= n; k ++) {
if(j == k) continue;
if(!(i & (1 << k - 1))) continue; //i中必须遍布k
f[i][j] = min(f[i][j], f[i ^ (1 << j - 1)][k] + s[k][j]);
}
}
}
printf("%d", f[maxn][n]);
}
以上是关于ybtoj 状压DP课堂过关AcWing 91最短 Hamilton 路径 &例题2最短路径的主要内容,如果未能解决你的问题,请参考以下文章