藍橋杯練習:最短Hamilton路徑

最短Hamilton路徑

在這裏插入圖片描述


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

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章