AcWing 91. 【JAVA】最短Hamilton路径
原题链接
中等
作者:
ianie
,
2020-02-14 18:25:37
,
所有人可见
,
阅读 756
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] weight = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
weight[i][j] = sc.nextInt();
}
}
//m为所有状态的二进制表示,如n=2时,m=100,可表示000 001 010 011四种状态
//即 都没经过 经过0号点 经过1号点 经过0号店和1号点四种情况
int m = 1 << n;
int dp[][] = new int[m][n];//第一维用下标表示所有状态,第二维下标表示点号,值表示目前总权
for(int i=0;i<m;i++) {//初始化所有权为+∞
Arrays.fill(dp[i], Integer.MAX_VALUE/4);//除小一点的数都可以,只是为了防止相加时溢出
}
dp[1][0]=0;//意味在出发点0号点,状态为000001(即只经历过0号点),权为0
for (int i = 0; i < m; i++) {//遍历所有状态
for (int j = 0; j < n; j++) {//遍历所有点
if (((i >> j) & 1) == 1) {//如果这种状态下经历过j号点
for (int k = 0; k < n; k++) {//搜索从k号点到j号点的最小权
if ((((i - (1 << j)) >> k) & 1) == 1) {
//如果该状态经历过k点但没有经历过j点,即是可行状态
//取转移中的最小值并记录
dp[i][j] = Math.min(dp[i][j], dp[i - (1 << j)][k] + weight[k][j]);
}
}
}
}
}
//则dp[m-1][n-1],即经历过所有点且终点在n-1号点时的权就是结果
System.out.println(dp[m-1][n-1]);
}
}