zoukankan      html  css  js  c++  java
  • BZOJ2595 [Wc2008]游览计划

    麻麻问我为什么跪倒在地

    这么高端的求法!!!spfa优化DP。。。

    等等,斯坦纳树的求法是DP?还是状压DP!Σ( ° △ °||)

    蒟蒻彻底跪了,还是Orz hzwer吧2333

      1 /**************************************************************
      2     Problem: 2595
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:160 ms
      7     Memory:4444 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <queue>
     12 #include <utility>
     13  
     14 #define P Point
     15 using namespace std;
     16 const int N = 15;
     17 const int maxS = 1024;
     18 const int inf = 1e9;
     19 const int dx[4] = {0, 0, 1, -1};
     20 const int dy[4] = {1, -1, 0, 0};
     21  
     22 int n, m, K;
     23 int a[N][N], bin[N];
     24 int f[N][N][maxS];
     25 bool inq[N][N], used[N][N];
     26  
     27 struct Point {
     28     int x, y;
     29     P() {}
     30     P(int _x, int _y) : x(_x), y(_y) {}
     31 };
     32 queue<P> q;
     33  
     34 struct Path {
     35     int x, y, s;
     36     Path() {}
     37     Path(int _f, int _s, int _t) : x(_f), y(_s), s(_t) {}
     38 } path[N][N][maxS];
     39  
     40 inline int read() {
     41     int x = 0;
     42     char ch = getchar();
     43     while (ch < '0' || '9' < ch)
     44         ch = getchar();
     45     while ('0' <= ch && ch <= '9') {
     46         x = x * 10 + ch - '0';
     47         ch = getchar();
     48     }
     49     return x;
     50 }
     51  
     52 void spfa(int S) {
     53     int k, x, y, X, Y;
     54     while (!q.empty()) {
     55         inq[x = q.front().x][y = q.front().y] = 0, q.pop();
     56         for (k = 0; k < 4; ++k) {
     57             X = x + dx[k], Y = y + dy[k];
     58             if (x < 1 || y < 1 || x > n || y > m) continue;
     59             if (f[X][Y][S] > f[x][y][S] + a[X][Y]) {
     60                 f[X][Y][S] = f[x][y][S] + a[X][Y];
     61                 path[X][Y][S] = Path(x, y, S);
     62                 if (!inq[X][Y])
     63                     q.push(P(X, Y)), inq[X][Y] = 1;
     64             }
     65         }
     66     }
     67 }
     68  
     69 #define t path[x][y][S]
     70 void dfs(int x, int y, int S) {
     71     if (x > inf || !path[x][y][S].s) return;
     72     used[x][y] = 1;
     73     dfs(t.x, t.y, t.s);
     74     if (t.x == x && t.y == y) dfs(x, y, S ^ t.s);
     75 }
     76 #undef t
     77  
     78 void read_in() {
     79     int i, j;
     80     n = read(), m = read();
     81     for (i = 1; i <= n; ++i)
     82         for (j = 1; j <= m; ++j)
     83             if (!(a[i][j] = read())) ++K;
     84     for (i = bin[0] = 1; i <= K; ++i)
     85         bin[i] = bin[i - 1] << 1;
     86 }
     87  
     88 void pre_work() {
     89     int i, j, k;
     90     for (i = 1; i <= n; ++i)
     91         for (j = 1; j <= m; ++j)
     92             for (k = 0; k < bin[K]; ++k)
     93                 f[i][j][k] = path[i][j][k].x = inf;
     94     for (i = 1, K = 0; i <= n; ++i)
     95         for (j = 1; j <= m; ++j)
     96             if (!a[i][j])
     97                 f[i][j][bin[K++]] = 0;
     98 }
     99  
    100 void work() {
    101     int i, j, S, s, tmp;
    102     for (S = 1; S < bin[K]; spfa(S++))
    103         for (i = 1; i <= n; ++i)
    104             for (j = 1; j <= m; ++j) {
    105                 for (s = S & (S - 1); s; s = S & (s - 1))
    106                     if ((tmp = f[i][j][s] + f[i][j][S ^ s] - a[i][j]) < f[i][j][S]) {
    107                         f[i][j][S] = tmp;
    108                         path[i][j][S] = Path(i, j, s);
    109                     }
    110                 if (f[i][j][S] != inf) {
    111                     q.push(P(i, j)), inq[i][j] = 1;
    112                 }
    113             }
    114 }
    115  
    116 void get_ans1() {
    117     int i, j;
    118     for (i = 1; i <= n; ++i)
    119         for (j = 1; j <= m; ++j) if (!a[i][j]) {
    120             dfs(i, j, bin[K] - 1);
    121             printf("%d
    ", f[i][j][bin[K] - 1]);
    122             return;
    123         }
    124 }
    125  
    126 void get_ans2() {
    127     int i, j;
    128     for (i = 1; i <= n; ++i, putchar('
    '))
    129         for (j = 1; j <= m; ++j)
    130             if (!a[i][j]) putchar('x'); else
    131             if (used[i][j]) putchar('o'); else
    132             putchar('_');
    133  
    134 }
    135  
    136 int main() {
    137     read_in();
    138     pre_work();
    139     work();
    140     get_ans1();
    141     get_ans2();
    142     return 0;
    143 }
    View Code

    (p.s.  这英文是叫Steiner Tree吧。。。)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    jquery 选择器
    LeetCode_217. Contains Duplicate
    LeetCode_206. Reverse Linked List
    LeetCode_205. Isomorphic Strings
    LeetCode_204. Count Primes
    LeetCode_203. Remove Linked List Elements
    LeetCode_202. Happy Number
    LeetCode_198. House Robber
    LeetCode_191. Number of 1 Bits
    LeetCode_190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/rausen/p/4194724.html
Copyright © 2011-2022 走看看