• 【bzoi2006】【狼抓兔子】【最小割】


    Description Source: Beijing2006 [BJOI2006]
    八中OJ上本题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001
    如今小朋友们最喜欢的”喜羊羊与灰太狼”,话说灰太狼抓羊不到,但抓兔子还是比較在行的。并且如今的兔子还比較笨,它们仅仅有两个窝,如今你做为狼王,面对以下这样一个网格的地形:
    这里写图片描写叙述

    左上角点为(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
    题解:转对偶图后跑最短路就好了。详细參见论文《两极相通——浅析最大—最小定理在信息学竞赛中的应用》
    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int cnt,point[1000001],dis[1000001],l[1000001],next[1000001],n,m,c,s,t,tt1;
    bool f[1000001];
    struct use{
        int st,en,val;
    }b[2000000];
    void add(int x,int y,int z)
    {
        next[++cnt]=point[x];point[x]=cnt;
        b[cnt].st=x;b[cnt].en=y;b[cnt].val=z;
        next[++cnt]=point[y];point[y]=cnt;
        b[cnt].st=y;b[cnt].en=x;b[cnt].val=z;
    }
    int spfa(int x,int y){    
        int h,t,u;memset(dis,127/3,sizeof(dis));   
        dis[x]=0;h=0;t=1;l[t]=x;  
        while(h<t){  
            u=l[++h];  
            for(int i=point[u];i;i=next[i]) 
                if(dis[b[i].en]>dis[u]+b[i].val&&u!=i){  
                    dis[b[i].en]=dis[u]+b[i].val;   
                    if(!f[b[i].en]){  
                        f[b[i].en]=true;  
                        l[++t]=b[i].en;  
                    }  
                }  
        }  
        return dis[y]>21000000?0:dis[y];  
    } 
    int main()
    {
        freopen("bjrabbit.in","r",stdin);
        freopen("bjrabbit.out","w",stdout);
        scanf("%d%d",&n,&m);
        t=2*m*n-2*m-2*n+4;tt1=2*(m-1)*(n-2);
        for (int i=1;i<=n;i++)
          for (int j=2;j<=m;j++){
              scanf("%d",&c);int temp=2*(m-1)*(i-2)+2*(j-1);
              if (i==1) add(i+2*(j-1),t,c);if (i==n) add(temp,s,c);
              if (i>1&&i<n) add(temp,temp+2*m-1,c);
            }
        for (int i=2;i<=n;i++)
          for (int j=1;j<=m;j++){
                int temp=2*(m-1)*(i-2)+2*(j-1);scanf("%d",&c);
                if (j==1) add(temp+2,s,c);if (j==m) add(temp+1,t,c);
                if (j>1&&j<m) add(temp+1,temp+2,c);
             }
        for (int i=2;i<=n;i++)
          for (int j=2;j<=m;j++){
              scanf("%d",&c);int temp=2*(m-1)*(i-2)+2*(j-1);
              add(temp,temp+1,c);
            }
        cout<<spfa(s,t)<<endl;
    }
  • 相关阅读:
    3D引擎为什么使用三角形绘制曲面
    用SublimeText当Unity Shader的编辑器
    Lua模块的加载与内存释放
    wriesharek同时监听多个端口
    Unity的Input输入
    Unity项目中文字的统一管理
    Unity中的定时器与延时器
    Unity插件扩展中组件常用的几个方法
    u3d不显示阴影的处理方法
    使用ScriptableObject创建.asset文件
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5277196.html
Copyright © 2020-2023  润新知