zoukankan      html  css  js  c++  java
  • [状态压缩DP] PKU 3311 Hie with the Pie

    和COJ送货到家一样,不过这里不要求每个点只经过一次,因此可以先用floyd预处理出任意两点间的最短距离,然后状态压缩DP。

    # include <cstdio>
    # include <cstring>
    
    # define INF 0x3C3C3C3C
    # define N 10 + 2
    
    int n;
    int w[N][N];
    int f[1<<N][N];
    
    int Min(int x, int y)
    {
        return x<y ? x:y;
    }
    
    int dp(int s, int i)
    {
        int &ans = f[s][i];
        if (ans != -1) return ans;
        int ns = s&(~(1<<i));
        if (ns == 1) return ans = w[0][i];
        ans = INF;
        for (int j = 1; j < n; ++j) if (((s>>j)&0x1) && j!=i)
        {
            ans = Min(ans, dp(ns, j)+w[j][i]);
        }
        return ans;
    }
    
    void solve(void)
    {
        int ans = INF;
        if (n==1) {puts("0");return ;}
        for (int i = 0; i < (1<<n); ++i)
            memset(f[i], -1, sizeof(int)*n);
           f[1][0] = 0;
        for (int i = 1; i < n; ++i)
        {
            ans = Min(ans, dp((1<<n)-1, i)+w[i][0]);
        }
        printf("%d\n", ans);
    }
    
    void read_graph(void)
    {
        for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            scanf("%d\n", &w[i][j]);
    }
    
    void rebuild_graph(void)
    {
        for (int k = 0; k < n; ++k)
        for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            w[i][j] = Min(w[i][j], w[i][k]+w[k][j]);        
    }
    
    int main()
    {    
        while (scanf("%d", &n), n)
        {
            ++n;
            read_graph();
            rebuild_graph();
            solve();
           }
               
        return 0;
    }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    leetcode 213. 打家劫舍 II JAVA
    leetcode 48. 旋转图像 java
    leetcode 45. 跳跃游戏 II JAVA
    leetcode 42. 接雨水 JAVA
    40. 组合总和 II leetcode JAVA
    24. 两两交换链表中的节点 leetcode
    1002. 查找常用字符 leecode
    leetcode 23. 合并K个排序链表 JAVA
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2624337.html
Copyright © 2011-2022 走看看