zoukankan      html  css  js  c++  java
  • BZOJ4006 [JLOI2015]管道连接

    裸的状压DP

    令$f_S$表示包含颜色集合S的最小斯坦纳生成森林的值,于是有:

    $$f_S=min{f_S,f_s+f_{S-s}|ssubset S}$$

    然后嘛。。。还是裸的斯坦纳树搞搞。。。又是个状压【摔!

    貌似会TLE的说【额。。。

    然后PoPoQQQ大爷分析了一番,说,大概1E的复杂度,不会T!

    好,那就不会好了!(也太不求上进了吧)

      1 /**************************************************************
      2     Problem: 4006
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:7272 ms
      7     Memory:5160 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 const int M = 3e3 + 5;
     16 const int N = 1e3 + 5;
     17 const int K = 25;
     18 const int Sz_q = N * 64;
     19 const int inf = 0x3f3f3f3f;
     20  
     21 inline int read();
     22  
     23 struct edge {
     24     int next, to, v;
     25     edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {}
     26 } e[M << 1];
     27  
     28 struct point {
     29     int c, w;
     30      
     31     inline void get() {
     32         c = read(), w = read();
     33     }
     34      
     35     inline bool operator < (const point &p) const {
     36         return c < p.c;
     37     }
     38 } p[K];
     39  
     40 int n, m, k, c, cnt;
     41 int first[N], tot;
     42 int f[1024][N], g[32];
     43 int l, r, q[Sz_q], v[N];
     44  
     45 inline void Add_Edges(int x, int y, int z) {
     46     e[++tot] = edge(first[x], y, z), first[x] = tot;
     47     e[++tot] = edge(first[y], x, z), first[y] = tot;
     48 }
     49  
     50 #define y e[x].to
     51 void spfa(int *dis) {
     52     static int x, p;
     53     while (l != (r + 1) % Sz_q) {
     54         p = q[l], v[p] = 0, ++l %= Sz_q;
     55         for (x = first[p]; x; x = e[x].next)
     56             if (dis[p] + e[x].v < dis[y]) {
     57                 dis[y] = dis[p] + e[x].v;
     58                 if (!v[y]) {
     59                     v[y] = 1;
     60                     if (dis[y] < dis[q[l]]) q[(l += Sz_q - 1) %= Sz_q] = y;
     61                     else q[++r %= Sz_q] = y;
     62                 }
     63             }
     64     }
     65 }
     66 #undef y
     67  
     68 int work() {
     69     static int S, s, i, res;
     70     for (S = 1; S < 1 << cnt; ++S) {
     71         for (i = 1; i <= n; ++i) {
     72             for (s = S & (S - 1); s; (--s) &= S)
     73                 f[S][i] = min(f[S][i], f[s][i] + f[S ^ s][i]);
     74             if (f[S][i] != inf) q[++r %= Sz_q] = i;
     75         }
     76         spfa(f[S]);
     77     }
     78     for (res = inf, i = 1; i <= n; ++i)
     79         res = min(res, f[(1 << cnt) - 1][i]);
     80     return res;
     81 }
     82  
     83 int main() {
     84     int i, x, y, z, S, s, nowc;
     85     n = read(), m = read(), k = read();
     86     for (i = 1; i <= m; ++i) {
     87         x = read(), y = read(), z = read();
     88         Add_Edges(x, y, z);
     89     }
     90     for (i = 1; i <= k; ++i) p[i].get();
     91     sort(p + 1, p + k + 1);
     92     for (nowc = -1, c = 0, i = 1; i <= k; ++i) {
     93         if (p[i].c != nowc) nowc = p[i].c, ++c;
     94         p[i].c = c;
     95     }
     96      
     97     memset(g, 0x3f, sizeof(g));
     98     for (S = 1; S < 1 << c; ++S) {
     99         for (cnt = 0, i = 1; i <= k; ++i)
    100             if (S & (1 << p[i].c - 1)) ++cnt;
    101         memset(f, 0x3f, sizeof(f[0][0]) * N * (1 << cnt));
    102         for (cnt = 0, i = 1; i <= k; ++i)
    103             if (S & (1 << p[i].c - 1)) f[1 << cnt++][p[i].w] = 0;
    104         g[S] = work();
    105     }
    106     for (S = 1; S < 1 << c; ++S)
    107         for (s = S & (S - 1); s; (--s) &= S)
    108             g[S] = min(g[S], g[s] + g[S ^ s]);
    109     printf("%d
    ", g[(1 << c) - 1]);
    110     return 0;
    111 }
    112  
    113 inline int read() {
    114     static int x;
    115     static char ch;
    116     x = 0, ch = getchar();
    117     while (ch < '0' || '9' < ch)
    118         ch = getchar();
    119     while ('0' <= ch && ch <= '9') {
    120         x = x * 10 + ch - '0';
    121         ch = getchar();
    122     }
    123     return x;
    124 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    NOIP模拟 10
    无聊的 邮递员 插头dp
    类实例化对象可以访问静态(static)方法,但是不能访问静态属性。
    PHP——抽象类与接口的区别
    工厂模式
    win10 专业版 git bash 闪退问题终极解决方案
    git基本的使用原理
    排序算法-插入排序
    如何进行CodeReview
    php中的各种http报错的报错的状态码的分析
  • 原文地址:https://www.cnblogs.com/rausen/p/4448784.html
Copyright © 2011-2022 走看看