• 【BZOJ1001】狼抓兔子


    1001: [BeiJing2006]狼抓兔子

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 7530  Solved: 1724
    [Submit][Status]

    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

     

    Source

    分析:根据题意很容易想到是(1,1)到(n,m)最大流,但最多会有10^6点,普通的会TLE。本屌丝当然也没招~~搜了题解,原来是2008周冬的集训队论文里提到的平面图的最大流——>最小割——>对偶图的最短路,于是可以最短路做,我用的是dijkstra+heap

    题解:关于平面图的最大流详见周冬的论文(AH的oier呢好骄傲~~~),这里我只想提一下,根据平面图的定义,几乎所有最大流问题都可以这样做,当然前提是容易判断各个面,目前我见到的只是这种网格网络流,求大神分享其他的……

    然后这题只剩建图了:大家自己在草稿纸画画就行了,我是将s点定为0,t点定为(n-1)*(m-1)*2+1(因为里面有(n-1)*(m-1)*2的三角形面),然后就是按顺序给里面的三角形编号,从左到右从上到下编号。然后有左边界或者下边界的连向s,有上边界或者右边界的连向t,中间的处理画画图谢谢式子就行了,具体看我程序

    注意:1、建图的时候左下角会连2次s,右上角会连2次t,所以要判重,取两条边中最小的

       2、特判m=1或n=1,ans是输入的数中的最小值

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<queue>
      4 #include<cstring>
      5 #include<vector>
      6 using namespace std;
      7 const int maxn=1000;
      8 const int maxm=1000;
      9 const int inf=1000000000;
     10 struct heap
     11 {
     12     int d,u;
     13     bool operator < (const heap& x) const
     14     {
     15         return d>x.d;
     16     }
     17 };
     18 priority_queue<heap> q;
     19 struct wjmzbmr
     20 {
     21     int to,data;
     22 };
     23 vector<wjmzbmr> g[(maxn-1)*(maxm-1)*2+50];
     24 int n,m,d[(maxn-1)*(maxm-1)*2+50],f[(maxn-1)*(maxm-1)*2+50];
     25 void ins(int a,int b,int w)
     26 {
     27     g[a].push_back({b,w});
     28     g[b].push_back({a,w});
     29 }
     30 int main()
     31 {    scanf("%d%d",&n,&m);
     32     for(int i=0;i<=(maxn-1)*(maxm-1)*2+1;++i) g[i].clear();
     33     if(n==1&&m==1) 
     34     {
     35     printf("0");
     36     return 0;
     37     }
     38     if(n==1)
     39     {
     40         int s=inf,x;
     41         for(int i=1;i<m;++i) scanf("%d",&x),s=min(s,x);
     42         printf("%d",s);
     43         return 0; 
     44     }
     45     if(m==1)
     46     {
     47         int s=inf,x;
     48         for(int i=1;i<n;++i) scanf("%d",&x),s=min(s,x);
     49         printf("%d",s);
     50         return 0; 
     51     }
     52     int s=0,t=(n-1)*(m-1)*2+1,a=inf,b=inf;
     53     for(int i=1;i<=n;++i)
     54         for(int j=1;j<m;++j) 
     55             {
     56                 int x;
     57                 scanf("%d",&x);
     58                 if(i==1&&j==m-1)
     59                 {
     60                     a=min(x,a);
     61                     continue;
     62                 }
     63                 if(i==n&&j==1)
     64                 {
     65                     b=min(x,b);
     66                     continue;
     67                 }
     68                 if(i==1) ins(j,t,x);
     69                 if(i==n) ins((n-2)*(m-1)*2+m-1+j,s,x);
     70                 if(i!=1&&i!=n) ins(2*(i-2)*(m-1)+m-1+j,2*(i-1)*(m-1)+j,x);
     71                 
     72             }
     73     for(int i=1;i<=n-1;++i)
     74         for(int j=1;j<=m;++j)
     75         {
     76             int x;
     77             scanf("%d",&x);
     78                 if(i==1&&j==m)
     79                 {
     80                     a=min(x,a);
     81                     continue;
     82                 }
     83                 if(i==n-1&&j==1)
     84                 {
     85                     b=min(x,b);
     86                     continue;
     87                 }
     88             if(j==1) ins(s,(i-1)*2*(m-1)+m,x);
     89             if(j==m) ins(t,(i-1)*2*(m-1)+m-1,x);
     90             if(j!=1&&j!=m) ins((i-1)*2*(m-1)+j-1,(i-1)*2*(m-1)+m-1+j,x);
     91         }
     92     for(int i=1;i<=n-1;++i)
     93         for(int j=1;j<=m-1;++j)
     94         {
     95             int x;
     96             scanf("%d",&x);
     97             ins((i-1)*2*(m-1)+j,(i-1)*(m-1)*2+m-1+j,x);
     98         }
     99     ins(m-1,t,a);ins(t-m+1,0,b);
    100     memset(f,0,sizeof(f));
    101     for(int i=s;i<=t;++i) d[i]=inf;d[s]=0;
    102     while(!q.empty())q.pop();
    103     q.push({0,s});
    104     while(!q.empty())
    105     {
    106         heap x=q.top();q.pop();
    107         if(f[x.u]==1) continue;
    108         f[x.u]=1;
    109         for(int i=0;i<g[x.u].size();++i)
    110             if(d[x.u]+g[x.u][i].data<d[g[x.u][i].to])
    111             {
    112                 d[g[x.u][i].to]=d[x.u]+g[x.u][i].data;
    113                 q.push({d[g[x.u][i].to],g[x.u][i].to});
    114             }
    115     }
    116     printf("%d",d[t]);
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    Atitit.struts2体系结构大总结
    Atitit.hibernate体系结构大总结
    Atitit. 最佳实践 QA----降低cpu占有率--cpu占用太高怎么办
    Atitit.软件GUI按钮与仪表盘(01)--js区-----js格式化的使用
    Atitit.软件控件and仪表盘(23)--多媒体子系统--视频输出切换控制cvbs av s-video Ypbpr pal ntsc
    Atitit.软件开发概念说明--io系统区--特殊文件名称保存最佳实践文件名称编码...filenameEncode
    Atitit.软件按钮与仪表盘(13)--全文索引操作--db数据库子系统mssql2008
    Atitit.软件GUI按钮与仪表盘(01)--报警系统--
    Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php
    Atitit.软件仪表盘(0)--软件的子系统体系说明
  • 原文地址:https://www.cnblogs.com/wmrv587/p/3486545.html
Copyright © 2020-2023  润新知