• 【BZOJ 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
     
    话说暴力出奇迹
    他们都说这个题是最小割,转对偶图之后跑最短路
    然而我并不会写对偶图,所以就网上扔了一个最大流,结果A了。。。
    如图建边,dinic一定要写的足够快,否则会T,比如像我
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 using namespace std;
     6 const int inf=100000000,N=1010000;
     7 struct ee{int to,next,f;}e[12000010];
     8 int head[N],q[N*2],dis[N];
     9 int S,T,n,m,cnt=1,ans,w;
    10  
    11 void ins(int u,int v,int f){
    12     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
    13     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
    14 }
    15  
    16 bool bfs(){
    17     for (int i=1;i<=T;i++) dis[i]=inf;
    18     int h=0,t=1,now;
    19     q[1]=S;dis[S]=0;
    20     while(h!=t){
    21         now=q[++h];
    22         for (int i=head[now];i;i=e[i].next){
    23             int v=e[i].to;
    24             if (e[i].f&&dis[now]+1<dis[v]){
    25                 dis[v]=dis[now]+1;
    26                 if (v==T)return 1;
    27                 q[++t]=v;
    28             }
    29         }
    30     }
    31     if (dis[T]==inf) return 0; return 1;
    32 }
    33  
    34 int dinic(int now,int f){
    35     if (now==T) return f;
    36     int rest=f;
    37     for (int i=head[now];i;i=e[i].next){
    38         int v=e[i].to;
    39         if (e[i].f&&dis[v]==dis[now]+1&&rest){
    40             int t=dinic(v,min(rest,e[i].f));
    41             if (!t) dis[v]=0;
    42             e[i].f-=t;
    43             e[i^1].f+=t;
    44             rest-=t;
    45             //if(t) printf("%d %d %d
    ",now,v,e[i].f);
    46         }
    47     }
    48     return f-rest;
    49 }
    50 int  main(){
    51     scanf("%d%d",&n,&m);
    52     S=0,T=n*m+1;
    53     ins(S,1,inf);ins(n*m,T,inf);
    54     for (int i=1;i<=n;i++)
    55         for (int j=1;j<=m-1;j++){
    56             scanf("%d",&w);
    57             int u=(i-1)*m+j;
    58             ins(u,u+1,w);
    59             ins(u+1,u,w);
    60         }
    61     for (int i=1;i<=n-1;i++)
    62         for (int j=1;j<=m;j++){
    63             scanf("%d",&w);
    64             int u=(i-1)*m+j;
    65             ins(u,u+m,w);
    66             ins(u+m,u,w);
    67         }
    68     for (int i=1;i<=n-1;i++)
    69         for(int j=1;j<=m-1;j++){
    70             scanf("%d",&w);
    71             int u=(i-1)*m+j;
    72             ins(u,u+m+1,w);
    73             ins(u+m+1,u,w);
    74         }
    75     while (bfs()) 
    76     ans+=dinic(S,inf); 
    77     printf("%d",ans);
    78     return 0;
    79 } 
    80 
  • 相关阅读:
    BD String
    1114
    1083
    1084
    1108
    1087
    1145
    1217
    1164
    反射
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5188299.html
Copyright © 2020-2023  润新知