BZOJ 1001 [BeiJing2006]狼抓兔子

来源:互联网 发布:python 读取 csv 编辑:程序博客网 时间:2024/05/18 23:14

题目描述 传送门
现在小朋友们最喜欢的”喜羊羊与灰太狼”,话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
这里写图片描述
左上角点为(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只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.


平面网格图求最小割转化为求最短路。
代码

#include<cstdio>#include<iostream>#include<cstring>#include<queue>#define FOR(I,A) for(int I=0;I<A;I++) using namespace std;const int maxm=6000000;struct Edge{    int to,dist,nxt;    Edge(int t=0,int d=0,int n=0):to(t),dist(d),nxt(n){}}E[maxm];int d[2000000],v[2000000],cnt=1,h[2000000];void addedge(int f,int t,int d){    E[cnt]=Edge(t,d,h[f]);    h[f]=cnt++;    E[cnt]=Edge(f,d,h[t]);    h[t]=cnt++;}int main(){    memset(h,0,sizeof(h));    int n,m;    cin>>n>>m;    int nm=(n-1)*(m-1)*2;    int x,a,b;    FOR(i,n) FOR(j,m-1){        scanf("%d",&x);        a=i*(m-1)*2+j*2+2;        b=a-(m-1)*2-1;        if(i==n-1) a=0;        if(i==0) b=nm+1;        addedge(a,b,x);    }    FOR(i,n-1) FOR(j,m){        scanf("%d",&x);        a=i*(m-1)*2+j*2+1;        b=a-1;        if(j==0) b=0;        if(j==m-1) a=nm+1;        addedge(a,b,x);    }    FOR(i,n-1) FOR(j,m-1){        scanf("%d",&x);        a=i*(m-1)*2+j*2+1;        b=a+1;        addedge(a,b,x);    }    FOR(i,nm+2) d[i]=1e9;    queue<int> q;                   //SPFA    q.push(0);    d[0]=0;    memset(v,0,sizeof(v));    while(!q.empty()){        int u=q.front();q.pop();v[u]=0;        for(int i=h[u];i;i=E[i].nxt){            Edge& e=E[i];            if(e.dist+d[u]<d[e.to]){                d[e.to]=e.dist+d[u];                if(!v[e.to]){                    q.push(e.to);                    v[e.to]=1;                }             }        }    }    cout<<d[nm+1]<<endl;                return 0;}
原创粉丝点击