这只是一道朴素的网络流
求出单位时间里最多能同时通过的兔子数就是需要的狼的数目
用了朴素的dinic方法
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define g getchar()
#define inf 0x3f3f3f3f
#define maxe 6000005
#define maxn 1000005
using namespace std;
struct re{int v,w,next;}ed[maxe];
int e,n,m,ans;
int head[maxn],dui[maxn],pd[maxn];
inline int read(){ //朴素的读入优化
int x=0,f=1;char ch=g;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=g;}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=g;}
return x*f;
}
void ins(int x,int y,int w){ //朴素的链式前向星
ed[++e].v=y;ed[e].next=head[x];ed[e].w=w;head[x]=e;
ed[++e].v=x;ed[e].next=head[y];ed[e].w=w;head[y]=e;
}
inline int min(int x,int y){ //朴素的较小值
return x<y?x:y;
}
void init(){ //朴素的init
n=read(),m=read();
for(int i=1;i<=n;++i)
for(int j=1;j<m;++j){
int x=read();
ins(m*(i-1)+j,m*(i-1)+j+1,x);
}
for(int i=1;i<n;++i)
for(int j=1;j<=m;++j){
int x=read();
ins(m*(i-1)+j,m*i+j,x);
}
for(int i=1;i<n;++i)
for(int j=1;j<m;++j){
int x=read();
ins(m*(i-1)+j,m*i+j+1,x);
}
}
bool bfs(){ //朴素的BFS判断是否存在增广路
int tou=1,wei=1;
dui[tou]=1;
memset(pd,-1,sizeof(pd));
pd[1]=0;
for(;tou<=wei;++tou){
int u=dui[tou];
for(int i=head[u];i;i=ed[i].next){
if(ed[i].w&&pd[ed[i].v]<0){
dui[++wei]=ed[i].v;
pd[ed[i].v]=pd[u]+1;
}
}
}
return pd[n*m]!=-1;
}
int dfs(int x,int w){ //朴素的DFS求增广路径的流量
if(x==n*m)return w;
int used=0,left;
for(int i=head[x];i;i=ed[i].next){
if(ed[i].w&&pd[ed[i].v]==pd[x]+1){
left=w-used;
left=dfs(ed[i].v,min(left,ed[i].w));
ed[i].w-=left;
ed[i%2?i+1:i-1].w+=left; //反向边加上相应流量
used+=left;
if(used==w)return w;
}
}
if(!used)pd[x]=-1;
return used;
}
int main(){ //仅有3行的主程序
init();
while(bfs())ans+=dfs(1,inf);
printf("%d",ans);return 0;
}