• BZOJ1001 [BeiJing2006]狼抓兔子


    一眼最小割,转化成最大流来做。

    然后发现点数达到10^6级别,妥妥TLE,于是需要进一步思考。

    由网上大量题解可知,一个图的最大流等于它的对偶图的最短路,于是只要Dijkstra就可以了。

    建图有点恶心。。。查了好长时间。。。

      1 /**************************************************************
      2     Problem: 1001
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:520 ms
      7     Memory:94588 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <queue>
     14  
     15 using namespace std;
     16  
     17 struct edges{
     18     int next, to, v;
     19 } e[6000005];
     20  
     21 struct heap_node{
     22     int v, to;
     23 };
     24 inline bool operator < (const heap_node &a, const heap_node &b){
     25     return a.v > b.v;
     26 }
     27  
     28 priority_queue <heap_node> h;
     29 heap_node NODE;
     30 int tot, S, T, n, m;
     31 int d[3000005], first[3000005];
     32 char ch;
     33  
     34 inline int read(){
     35     int x = 0, sgn = 1;
     36     ch = getchar();
     37     while (ch < '0' || ch > '9'){
     38         if (ch == '-') sgn = -1;
     39         ch = getchar();
     40     }
     41     while (ch >= '0' && ch <= '9'){
     42         x = x * 10 + ch - '0';
     43         ch = getchar();
     44     }
     45     return sgn * x;
     46 }
     47  
     48 inline void add_edge(int x, int y, int v){
     49     e[++tot].next = first[x], first[x] = tot;
     50     e[tot].to = y, e[tot].v = v;
     51 }
     52  
     53 void add_Edges(const int x, const int y, const int v){
     54     add_edge(x, y, v);
     55     add_edge(y, x, v);
     56 }
     57  
     58 inline void add_to_heap(const int p){
     59     for (int x = first[p]; x; x = e[x].next)
     60         if (d[e[x].to] == -1){
     61             NODE.v = e[x].v + d[p], NODE.to = e[x].to;
     62             h.push(NODE);
     63         }
     64 }
     65  
     66 int Dijkstra(int S, int T){
     67     memset(d, -1, sizeof(d));
     68     while (!h.empty()) h.pop();
     69     d[S] = 0, add_to_heap(S);
     70     int p;
     71     while (d[T] == -1){
     72         while (d[h.top().to] != -1) h.pop();
     73         p = h.top().to;
     74         d[p] = h.top().v;
     75         h.pop();
     76         add_to_heap(p);
     77     }
     78     return d[T];
     79 }
     80  
     81 void build_graph(){
     82     int Cost, x, y;
     83     for (int i = 1; i <= n; ++i)
     84         for (int j = 1; j < m; ++j){
     85             Cost = read();
     86             x = i == 1 ? S : (2 * i - 3) * (m - 1) + j;
     87             y = i == n ? T : (2 * i - 2) * (m - 1) + j;
     88             add_Edges(x, y, Cost);
     89         }
     90     for (int i = 1; i < n; ++i)
     91         for (int j = 1; j <= m; ++j){
     92             Cost = read();
     93             x = j == 1 ? T : 2 * (i - 1) * (m - 1) + j - 1;
     94             y = j == m ? S : 2 * (i - 1) * (m - 1) + j - 1 + m;
     95             add_Edges(x, y, Cost);
     96         }
     97     for (int i = 1; i < n; ++i)
     98         for (int j = 1; j < m; ++j){
     99             Cost = read();
    100             x = (2 * i - 2) * (m - 1) + j;
    101             y = (2 * i - 1) * (m - 1) + j;
    102             add_Edges(x, y, Cost);
    103         }
    104 }
    105  
    106 int main(){
    107     n = read(), m = read();
    108     if (n == 1 && m == 1){
    109         printf("%d
    ", 0);
    110         return 0;
    111     }
    112      
    113     S = 0, T = 2 * (m - 1) * (n - 1) + 1;
    114     build_graph();         
    115     printf("%d
    ", Dijkstra(S, T));
    116     return 0;
    117 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    写代码实现两个 goroutine,其中一个产生随机数并写入到 go channel 中,另外一 个从 channel 中读取数字并打印到标准输出。最终输出五个随机数。
    05| RWMutex:读写锁的实现原理及避坑指南
    go 面试题
    go 局部变量在哪
    12 _ atomic:要保证原子操作,一定要使用这几种方法
    11 _ Context:信息穿透上下文
    什么是线程
    go面试题
    redis连接池 go
    docker 指定版本rpm包安装
  • 原文地址:https://www.cnblogs.com/rausen/p/4034872.html
Copyright © 2020-2023  润新知