zoukankan      html  css  js  c++  java
  • [BeiJing2006]狼抓兔子

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 21218  Solved: 5311
    [Submit][Status][Discuss]

    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

    HINT

     2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

    思路:最小割转最大流

    然而我的第二种方法本来应该更偏向于正解,却被bzoj的极限数据T掉了,可能是我技巧不够高吧。

    170404:对偶图重新构图+最短路看起来更吊,然而结果得不偿失。

    代码实现:

    最大流 1001 Accepted 129728 kb 1512 ms C++/Edit 1775 B 2017-03-18 08:50:39
     1 #include<cstdio>
     2 #include<cstring>
     3 #define inf 1000000000
     4 int n,m,s,t,ans;
     5 int a,b,c,hs=1,head,tail;
     6 int h[3000010],d[3000010],q[3000010];
     7 struct edge{int s,n,w;}e[8000010];
     8 inline int min(int x,int y){return y<x?y:x;}
     9 char ch[30];
    10 int read(){
    11     int ret=0,l=0;
    12     do{ch[0]=getchar();}while(ch[0]<'0'||ch[0]>'9');
    13     l++;
    14     do{ch[l++]=getchar();}while(ch[l-1]>='0'&&ch[l-1]<='9');
    15     l-=2;
    16     for(int i=l,j=1;i>=0;i--,j*=10) ret+=(ch[i]-'0')*j;
    17     return ret;
    18 }
    19 void bfs(){
    20     memset(d,0,sizeof(d));
    21     head=tail=0;
    22     q[head++]=s,d[s]=1;
    23     while(head>tail){
    24         a=q[tail++];
    25         for(int i=h[a];i;i=e[i].n) if(!d[e[i].s]&&e[i].w){
    26             d[e[i].s]=d[a]+1;
    27             if(e[i].s==t) return;
    28             q[head++]=e[i].s;
    29         }
    30     }
    31 }
    32 int ap(int k,int v){
    33     if(k==t) return v;
    34     int act=v;
    35     for(int i=h[k];i;i=e[i].n)
    36     if(e[i].w&&d[e[i].s]==d[k]+1&&act){
    37         int ret=ap(e[i].s,min(act,e[i].w));
    38         if(ret) e[i].w-=ret,e[i^1].w+=ret,act-=ret;
    39         else d[e[i].s]=0;
    40     }
    41     return v-act;
    42 }
    43 bool Dinic(){
    44     bfs();
    45     if(!d[t]) return 0;
    46     ans+=ap(s,inf);
    47 }
    48 int main(){
    49     n=read(),m=read();
    50     s=1,t=n*m;
    51     for(int i=0;i<n;i++)
    52     for(int j=1;j<m;j++){
    53         c=read();
    54         a=i*m+j,b=a+1;
    55         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    56         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    57     }
    58     for(int i=0;i<n-1;i++)
    59     for(int j=1;j<=m;j++){
    60         c=read();
    61         a=i*m+j,b=a+m;
    62         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    63         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    64     }
    65     for(int i=0;i<n-1;i++)
    66     for(int j=1;j<m;j++){
    67         c=read();
    68         a=i*m+j,b=a+m+1;
    69         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    70         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    71     }
    72      
    73     while(Dinic());
    74     printf("%d
    ",ans);
    75     return 0;
    76 }
    对偶图 1001 Time_Limit_Exceed 149260 kb 15784 ms C++/Edit 1651 B 2017-03-15 20:52:11
     1 #include<cstdio>
     2 #include<cstring>
     3 int n,m,s,t;
     4 int a,b,c,hs=1,head,tail;
     5 int h[3000010],w[3000010],q[8000010];
     6 struct edge{int s,n,w;}e[8000010];
     7 inline bool bj(long long x,long long y,long long z){return y+z<x?1:0;}
     8 char ch[30];
     9 int read(){
    10     int ret=0,l=0;
    11     do{ch[0]=getchar();}while(ch[0]<'0'||ch[0]>'9');
    12     l++;
    13     do{ch[l++]=getchar();}while(ch[l-1]>='0'&&ch[l-1]<='9');
    14     l-=2;
    15     for(int i=l,j=1;i>=0;i--,j*=10) ret+=(ch[i]-'0')*j;
    16     return ret;
    17 }
    18 int main(){
    19     n=read(),m=read();
    20     s=m+1,t=2*n*m+2*n-m;
    21     for(int i=1;i<m;i++){
    22         a=i+1,b=i+t;
    23         e[++hs]=(edge){a,h[s]},h[s]=hs;
    24         e[++hs]=(edge){t,h[b]},h[b]=hs;
    25     }
    26     for(int i=2;i<2*n;i++){
    27         a=i*m+i,b=i*m+i-m;
    28         e[++hs]=(edge){a,h[s]},h[s]=hs;
    29         e[++hs]=(edge){t,h[b]},h[b]=hs;
    30     }
    31     for(int i=1;i<=n;i++)
    32     for(int j=1;j<m;j++){
    33         c=read();
    34         a=(2*i-2)*(m+1)+j+1,b=a+m+1;
    35         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    36         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    37     }
    38     for(int i=1;i<n;i++)
    39     for(int j=1;j<=m;j++){
    40         c=read();
    41         a=(i*2)*(m+1)+j+1,b=a-m-2;
    42         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    43         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    44     }
    45     for(int i=1;i<n;i++)
    46     for(int j=1;j<m;j++){
    47         c=read();
    48         a=(2*i-1)*(m+1)+j+1,b=a+m+1;
    49         e[++hs]=(edge){b,h[a],c},h[a]=hs;
    50         e[++hs]=(edge){a,h[b],c},h[b]=hs;
    51     }
    52     memset(w,0x7f,sizeof(w));
    53     q[head++]=s,w[s]=0;
    54     while(head>tail){
    55         a=q[tail++];
    56         for(int i=h[a];i;i=e[i].n)
    57         if(bj(w[e[i].s],w[a],e[i].w)){
    58             w[e[i].s]=w[a]+e[i].w;
    59             q[head++]=e[i].s;
    60         }
    61     }
    62     printf("%d
    ",w[t]);
    63     return 0;
    64 }
    65 

    建议先去COGS做一下,然后再去bzoj交。

    题目来源:bzoj

  • 相关阅读:
    HTML学习记录之HTML组成原理 PHP学习铺垫
    最长上升子序列(Longest increasing subsequence)
    进程保护(二)
    进程保护(一)
    屏幕广播的实现(三)
    vs2010 调试快捷键
    [整理]C#.Net的常见面试试题附答案(ZT)
    C# 中处理字符串常用的函数及方法详细说明
    Linux 系统下 /etc/group 档案结构
    C# Thread 多种写法总结
  • 原文地址:https://www.cnblogs.com/J-william/p/6571199.html
Copyright © 2011-2022 走看看