• bestcoder Round#52 1001(最短路+状压dp)


    求从1点出发,走遍所有的点,然后回到1点的最小代价。

    每个点可以走若干遍。

    如果每个点只能走一遍,那么设dp[i][s]为走完s状态个点(s是状态压缩),现在位于i的最小花费。

    然后枚举从哪个点回到原点即可。

    但是现在每个点不止走一次,那么状态就不好表示了,但是,我们可以用floyd处理出任意两点的最短距离。

    这样子,可以用上面的方式求解了。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <queue>
      7 #include <stack>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <math.h>
     13 using namespace std;
     14 #pragma warning(disable:4996)
     15 #pragma comment(linker, "/STACK:1024000000,1024000000")
     16 typedef __int64 LL;                   
     17 const int INF = 100000000;
     18 /*
     19 
     20 
     21 
     22 */
     23 int dp[17][70000];
     24 int dist[20][20];
     25 int g[20][20];
     26 void input(int &x)
     27 {
     28     char ch = getchar();
     29     while (ch<'0' || ch>'9')ch = getchar();
     30     x = 0;
     31     while (ch >= '0'&&ch <= '9')
     32     {
     33         x = x * 10 + ch - '0';
     34         ch = getchar();
     35     }
     36 }
     37 int ans;
     38 
     39 int main()
     40 {
     41     //freopen("d:/1.in", "r", stdin);
     42     int t, n, m, u, v,dis;
     43     scanf("%d", &t);
     44     while (t--)
     45     {
     46         scanf("%d%d", &n, &m);
     47         for (int i = 0; i <= n; ++i)
     48         for (int j = 0; j <= n; ++j)
     49         {
     50             g[i][j] = INF;
     51         }
     52         for (int i = 0; i < m; ++i)
     53         {
     54             input(u);
     55             input(v);
     56             input(dis);
     57             u--;
     58             v--;
     59             if (g[u][v]>dis)
     60                 g[u][v] = g[v][u] = dis;
     61         }
     62         for (int k = 0; k < n; ++k)
     63         {
     64             for (int i = 0; i < n;++i)
     65             for (int j = 0; j < n; ++j)
     66                 g[i][j] = min(g[i][j],g[i][k]+ g[k][j]);
     67         }
     68         
     69         
     70         for (int i = 0; i <= n; ++i)
     71         for (int s = 0; s < (1 << n); ++s)
     72             dp[i][s] = INF;
     73         dp[0][1] = 0;
     74         for (int s = 1; s < (1 << n); ++s)
     75         {
     76             for (int i = 0; i < n; ++i)
     77             {
     78                 if (s&(1 << i))
     79                 {
     80                     for (int j = 0; j < n; ++j)
     81                     {
     82                         if (!(s&(1 << j)))
     83                         {
     84                             dp[j][s | (1 << j)] = min(dp[j][s | (1 << j)], dp[i][s] + g[i][j]);
     85                         }
     86                     }
     87                 }
     88             }
     89         }
     90         if (n == 1)
     91         {
     92             printf("%d
    ", 0);
     93             continue;
     94         }
     95         int ans = INF;
     96         for (int i = 1; i < n; ++i)
     97         {
     98             ans = min(dp[i][(1 << n) - 1] + g[i][0], ans);
     99         }
    100         printf("%d
    ", ans);
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    C#基础
    C#基础
    Sqlserver数据库备份和还原
    C#基础
    Python3学习笔记4
    Python3学习笔记3
    调用接口Post xml和json数据的通用方法
    Python3学习笔记2
    Python3学习笔记1
    常见的PHP函数代码性能对比
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4751058.html
Copyright © 2020-2023  润新知