• BZOJ 1001 [BeiJing2006]狼抓兔子



    1001: [BeiJing2006]狼抓兔子

    Description

    现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

     

    左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 
    1:(x,y)<==>(x+1,y) 
    2:(x,y)<==>(x,y+1) 
    3:(x,y)<==>(x+1,y+1) 
    道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

    Input

    第一行为N,M.表示网格的大小,N,M均小于等于1000.
    接下来分三部分
    第一部分共N行,每行M-1个数,表示横向道路的权值. 
    第二部分共N-1行,每行M个数,表示纵向道路的权值. 
    第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 
    输入文件保证不超过10M

    Output

    输出一个整数,表示参与伏击的狼的最小数量.

    Sample Input

    3 4
    5 6 4
    4 3 1
    7 5 3
    5 6 7 8
    8 7 6 5
    5 5 5
    6 6 6

    Sample Output

    14

      用来验证模板的题目。看似只有1000,但其实规模很大,让我多次JIJI。
      最大流=最小割,本人蒟蒻,只会DINIC。什么ISAP统统不会。
     1 /**************************************************************
     2     Problem: 1001
     3     User: Doggu
     4     Language: C++
     5     Result: Accepted
     6     Time:2032 ms
     7     Memory:122924 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <cstring>
    13 #include <queue>
    14 #define pos(x,y) ((x-1)*m+y)
    15  
    16 const int M = 7000000 + 10;
    17 const int N = 1000000 + 10;
    18 struct Edge {int v, upre, cap, flow;}g[M];
    19 int head[N], ne = 0;
    20 inline void adde(int u,int v,int cap) {
    21     //printf("ADDE:%d %d %d
    ",u,v,cap);
    22     g[ne]=(Edge){v,head[u],cap,0};head[u]=ne++;
    23     g[ne]=(Edge){u,head[v],cap,0};head[v]=ne++;
    24 }
    25  
    26 int n, m, u, v, cap, s, t;
    27 struct DINIC {
    28     int d[N];
    29     bool vis[N];
    30     std::queue<int> q;
    31     bool BFS() {//建立层次图 
    32         memset(vis, 0, sizeof(vis));
    33         while(!q.empty()) q.pop();
    34         vis[s] = 1;d[s] = 0;q.push(s);
    35         while(!q.empty()) {
    36             int u = q.front();q.pop();
    37             for( int i = head[u]; i != -1; i = g[i].upre ) {
    38                 int v = g[i].v;
    39                 if(!vis[v] && g[i].cap>g[i].flow) vis[v] = 1, d[v] = d[u] + 1, q.push(v);
    40             }
    41         }
    42         return vis[t];
    43     }   
    44      
    45     int cur[N];
    46     int DFS(int u,int a) {//找增广路 
    47         if(u == t||a == 0) return a;//注意是return a 
    48         int f, flow = 0;
    49         for( int& i = cur[u]; i != -1; i = g[i].upre ) {//不要忘了加cur 
    50             int v = g[i].v;
    51             if(d[u] + 1 == d[v] && (f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
    52                 g[i].flow+=f;g[i^1].flow-=f;flow+=f;a-=f;//加加减减 
    53                 if(a==0) break;
    54             }
    55         }
    56         return flow;
    57     }
    58     void maxflow() {
    59         int flow = 0;
    60         while(BFS()) {
    61             memcpy(cur,head,sizeof(head));//每一次清零 
    62             flow += DFS(s,0x3f3f3f3f);
    63         }
    64         printf("%d
    ",flow);
    65     }
    66 }dinic;
    67 int main() {
    68     memset(head,-1,sizeof(head));
    69     scanf("%d%d",&n,&m);
    70     for( int x = 1; x <= n; x++ ) for( int y = 1; y < m; y++ ) {
    71         scanf("%d",&cap);
    72         adde(pos(x,y),pos(x,y+1),cap);
    73         //adde(pos(x,y+1),pos(x,y),cap);
    74     }
    75     for( int x = 1; x < n; x++ ) for( int y = 1; y <= m; y++ ) {
    76         scanf("%d",&cap);
    77         adde(pos(x,y),pos(x+1,y),cap);
    78         //adde(pos(x+1,y),pos(x,y),cap);
    79     }
    80     for( int x = 1; x < n; x++ ) for( int y = 1; y < m; y++ ) {
    81         scanf("%d",&cap);
    82         adde(pos(x,y),pos(x+1,y+1),cap);
    83         //adde(pos(x+1,y+1),pos(x,y),cap);
    84     }
    85     s=pos(1,1);t=pos(n,m);
    86     dinic.maxflow();
    87     return 0;
    88 }
    89 
    DINIC
     
     
  • 相关阅读:
    2017-12 CDQZ集训(已完结)
    BZOJ1492 货币兑换 CDQ分治优化DP
    BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治
    树套树小结
    跑路了
    NOI2020 游记
    半平面交模板
    Luogu 3245 大数
    Luogu 3246 序列
    test20190408(十二省联考)
  • 原文地址:https://www.cnblogs.com/Doggu/p/bzoj1001.html
Copyright © 2020-2023  润新知