• NOIP 2017 宝藏


    题目传送门

      传送门

    题目大意

      (家喻户晓的题目不需要题目大意)

      设$f_{d, s}$表示当前树的深度为$d$,与第一个打通的点连通的点集为$s$。

      每次转移的时候不考虑实际的深度,深度都当做$d$,寻找连接两个点集最小边集,如果能连接更浅的点,那么会在之前转移,所以即使转移非法也不可能成为最优解。

      找连接两个点集的最小边集合可以预处理。

      我比较懒,不想预处理,时间复杂度$O(n^{2}3^{n})$。

    Code

     1 /**
     2  * uoj
     3  * Problem#333
     4  * Accepted
     5  * Time: 123ms
     6  * Memory: 1412k
     7  */
     8 #include <iostream>
     9 #include <cstdlib>
    10 #include <cstdio>
    11 using namespace std;
    12 typedef bool boolean;
    13 
    14 const int N = 12, S = 1 << N;
    15 const signed inf = (signed) (~0u >> 1);
    16 
    17 template <typename T>
    18 void pfill(T* pst, const T* ped, T val) {
    19     for ( ; pst != ped; *(pst++) = val);
    20 }
    21 
    22 int n, m;
    23 int g[N][N];
    24 int f[N + 1][S];
    25 int cost[S];
    26 
    27 inline void init() {
    28     scanf("%d%d", &n, &m);
    29     for (int i = 0; i < n; i++)
    30         for (int j = 0; j < n; j++)
    31             g[i][j] = inf;
    32     for (int i = 0, u, v, w; i < m; i++) {
    33         scanf("%d%d%d", &u, &v, &w), u--, v--;
    34         g[v][u] = g[u][v] = min(g[u][v], w);
    35     }
    36 }
    37 
    38 int id[S];
    39 inline void solve() {
    40     int S = (1 << n);
    41     pfill(f[1], f[n + 1], inf);
    42     pfill(cost, cost + S, inf);
    43     for (int i = 0; i < n; i++)
    44         id[1 << i] = i;
    45     for (int i = 0; i < n; i++)
    46         f[1][1 << i] = 0;
    47     int ans = f[0][S - 1];
    48     for (int d = 2; d <= n; d++) {
    49         for (int s = 0, val; s < S; s++) {
    50             if ((val = f[d - 1][s]) == inf)
    51                 continue;
    52             cost[0] = 0;
    53             for (int ns = (s + 1) | s, cs, w, wc, cur; ns < S; ns = (ns + 1) | s) {
    54                 cs = (ns ^ s), w = cost[cs ^ (cs & (-cs))], wc = inf;
    55                 if (w == inf)
    56                     continue;
    57                 cur = id[(cs & (-cs))];
    58                 for (int i = 0; i < n; i++)
    59                     if (s & (1 << i))
    60                         wc = min(wc, g[cur][i]);
    61                 if (wc == inf)
    62                     continue;
    63                 f[d][ns] = min(f[d][ns], val + (w + wc) * (d - 1));
    64                 cost[cs] = w + wc;
    65             }
    66 
    67             for (int ns = s; ns < S; ns = (ns + 1) | s)
    68                 cost[ns ^ s] = inf;
    69         }
    70         ans = min(ans, f[d][S - 1]);
    71     }
    72     printf("%d
    ", ans);
    73 }
    74 
    75 int main() {
    76     init();
    77     solve();
    78     return 0;
    79 }
  • 相关阅读:
    box-shadow中的理解(bootstrap)
    setTimeout用于取消多次执行mouseover或者mouseenter事件,间接实现hover的悬停加载的效果.
    把之前能运行的springboot项目重新打开运行,报错 Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
    angularjs服务json文件实现省市区三级联动
    js页面用户信息填写表单
    js页面中实现加载更多功能
    遇见未知的自己
    ASP.NET Core 入门教程1 ASP.NET Core 读取配置文件
    有一种选择叫女程(5)
    有一种选择叫女程(4)
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9908573.html
Copyright © 2020-2023  润新知