1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 19528  Solved: 4818
[Submit][Status][Discuss]

Description

现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

 BZOJ1001: [BeiJing2006]狼抓兔子 [最小割 | 对偶图+spfa]

左上角点为(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新加数据一组,可能会卡掉从前可以过的程序。


就是用狼把这个图割开
或者想最多兔子量,然后一个兔子一个狼
 
法1:dinic
注意这是无向图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e6+5,INF=1e9;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,c,s,t;
struct edge{
    int v,ne,c,f;
}e[N*6];
int cnt,h[N];
inline void ins(int u,int v,int c){//printf("ins %d %d %d\n",u,v,c);
    cnt++;
    e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[u];h[u]=cnt;
    cnt++;
    e[cnt].v=u;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[v];h[v]=cnt;
}
inline int id(int i,int j){return (i-1)*m+j;}
int vis[N],d[N],q[N],head,tail;
inline void lop(int &x){if(x==N)x=1;}
bool bfs(){
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    head=tail=1;
    q[tail++]=s;d[s]=0;vis[s]=1;
    while(head!=tail){
        int u=q[head++];lop(head);
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!vis[v]&&e[i].c>e[i].f){
                vis[v]=1;d[v]=d[u]+1;
                q[tail++]=v;lop(tail);
                if(v==t) return true;
            }
        }
    }
    return false;
}
int cur[N];
int dfs(int u,int a){
    if(u==t||a==0) return a;
    int flow=0,f;
    for(int &i=cur[u];i;i=e[i].ne){
        int v=e[i].v;
        if(d[v]==d[u]+1&&(f=dfs(v,min(a,e[i].c-e[i].f)))>0){
            flow+=f;
            e[i].f+=f;
            e[((i-1)^1)+1].f-=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}
int dinic(){
    int flow=0;
    while(bfs()){
        for(int i=s;i<=t;i++) cur[i]=h[i];
        flow+=dfs(s,INF);//printf("dinic %d\n",flow);
    }
    return flow;
}
int main(){
    n=read();m=read();s=id(1,1);t=n*m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m-1;j++){c=read();ins(id(i,j),id(i,j+1),c);}
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=m;j++) {c=read();ins(id(i,j),id(i+1,j),c);}
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=m-1;j++){c=read();ins(id(i,j),id(i+1,j+1),c);}
    int ans=dinic();
    printf("%d",ans);
}
View Code

相关文章:

  • 2021-10-14
  • 2021-12-09
  • 2021-10-10
  • 2022-01-31
  • 2021-12-31
猜你喜欢
  • 2021-08-27
  • 2021-08-28
  • 2022-12-23
  • 2021-07-03
  • 2022-12-23
  • 2021-06-08
  • 2021-09-26
相关资源
相似解决方案