状压dp1

题解 alt alt

package com.zhang.reflection.面试.算法模版.动态规划;
import java.io.*;
import java.util.*;
/**
 * 描述
 * 今天春天铁子的班上组织了一场春游,在铁子的城市里有n个郊区和m条无向道路,第i条道路连接郊区Ai和Bi,路费是Ci。
 * 经过铁子和顺溜的提议,他们决定去其中的R个郊区玩耍(不考虑玩耍的顺序),但是由于他们的班费紧张,所以需要找到一条旅游路线使得他们的花费最少,假设他们制定的旅游路线为V1, V2 ,V3 ... VR,那么他们的总花费为从V1到V2的花费加上V2到V3的花费依次类推,注意从铁子班上到V1的花费和从VR到铁子班上的花费是不需要考虑的,因为这两段花费由学校报销而且我们也不打算告诉你铁子学校的位置。
 * 输入描述:
 * 第一行三个整数n, m, R(2 ≤ n ≤ 200, 1 ≤ m ≤ 5000, 2 ≤ R ≤ min(n, 15))。
 * 第二行R个整数表示需要去玩耍的郊区编号。
 * 以下m行每行Ai, Bi, Ci(1 ≤ Ai, Bi ≤ n, Ai ≠ Bi, Ci ≤ 10000)
 * 保证不存在重边。
 *
 * 4 6 3
 * 2 3 4
 * 1 2 4
 * 2 3 3
 * 4 3 1
 * 1 4 1
 * 4 2 2
 * 3 1 6
 *
 * 3
 */
public class 状压dp1 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] arr = br.readLine().split(" ");
        //n个郊区
        int n = Integer.parseInt(arr[0]);
        //m条通路
        int m = Integer.parseInt(arr[1]);
        //去R个郊区
        int r = Integer.parseInt(arr[2]);

        arr = br.readLine().split(" ");
        //去这几个郊区玩
        int[] go = new int[r];
        for (int i = 0; i < r; i++) {
            go[i] = Integer.parseInt(arr[i]);
        }

        //init matrix matrix[i][j]表示i到j的最短路径
        int[][] matrix = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            //相加超出int了
//            Arrays.fill(matrix[i], Integer.MAX_VALUE);
            Arrays.fill(matrix[i], 1000000000);
            matrix[i][i] = 0;
        }

        int a, b, cost;
        for (int i = 0; i < m; i++) {
            arr = br.readLine().split(" ");
            //相连的郊区及花费
            a = Integer.parseInt(arr[0]);
            b = Integer.parseInt(arr[1]);
            cost = Integer.parseInt(arr[2]);
//            matrix[a][b] = Math.min(matrix[a][b], cost);
//            matrix[b][a] = matrix[a][b];
            matrix[a][b] = cost;
            matrix[b][a] = cost;
        }

        //floyd算法 求两点间最小距离
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                for (int k = 1; k <= n; k++) {
                    matrix[j][k] = Math.min(matrix[j][k], matrix[j][i] + matrix[i][k]);
                }
            }
        }

        //init dp
        int t = 1 << r;
        int[][] dp = new int[t][r];
        for (int i = 0; i < t; i++) {
            Arrays.fill(dp[i], Integer.MAX_VALUE);
        }
        for (int i = 0; i < r; i++) {
            dp[1 << i][i] = 0;
        }

        //枚举i,j,k。状态转移
        for (int i = 1; i < t ; i++) {
            for (int j = 0; j < r; j++) {
                if ((i & (1 << j)) > 0) {
                    for (int k = 0; k < r; k++) {
                        if ((i & (1 << k)) == 0) {
                            dp[i + (1 << k)][k] = Math.min(dp[i + (1 << k)][k], dp[i][j] + matrix[go[j]][go[k]]);
                        }
                    }
                }
            }
        }

        //取最小值
        int ans = Integer.MAX_VALUE;
        for(int i = 0; i < r; i++) {
            ans = Math.min(ans, dp[t - 1][i]);
        }
        System.out.println(ans);
    }
}
全部评论

相关推荐

有没有友友知道hr面会问什么我应该反问什么?还有如何防止hr套话啊?还有应该如果催hr推进快一点#字节#OPPO#hr面
牛客989988346号:职业规划,优缺点,为什么选择这个岗,对应聘公司产品的了解和满意度,如果让你改进公司产品你会怎么做,对ai(新技术)的了解,有无其他offer,什么时候能到岗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务