Blue Bridge Cup Practice 10: Hamilton shortest path

Hamilton shortest path

Here Insert Picture Description


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 = 1; 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]);
	}

}

Published 41 original articles · won praise 1 · views 1437

Guess you like

Origin blog.csdn.net/qq_44467578/article/details/104316892