您的位置:首页 > 其它

【bzoj 1001】狼抓兔子(最小割)

2017-10-03 22:58 253 查看
传送门biu~

因为是无向图,所以建图的时候不要存反向边,把一个边正反存两次,然后直接跑一遍Dinic就可以了。注意当前弧优化,不优化会TLE。

#include<bits/stdc++.h>
#define INF 0x7fffffff
using namespace std;
int n,m,s,t;
int head[1000005],nex[6000005],to[6000005],cap[6000005],tp=1;
int dep[1000005],fir[1000005];
inline void add(int x,int y,int v){
nex[++tp]=head[x];
head[x]=tp;
to[tp]=y;
cap[tp]=v;
}
inline void init(){
scanf("%d%d",&n,&m);
s=1;t=n*m;
for(int i=1;i<=n;++i){
for(int j=1;j<=m-1;++j){
int x;
scanf("%d",&x);
add(m*(i-1)+j,m*(i-1)+j+1,x);
add(m*(i-1)+j+1,m*(i-1)+j,x);
}
}
for(int i=1;i<=n-1;++i){
for(int j=1;j<=m;++j){
int x;
scanf("%d",&x);
add(m*(i-1)+j,m*i+j,x);
add(m*i+j,m*(i-1)+j,x);
}
}
for(int i=1;i<=n-1;++i){
for(int j=1;j<=m-1;++j){
int x;
scanf("%d",&x);
add(m*(i-1)+j,m*i+j+1,x);
add(m*i+j+1,m*(i-1)+j,x);
}
}
}
int dfs(int x,int now){
int c=0;
if(x==t || !now)        return now;
for(int &i=fir[x];i;i=nex[i]){
if(dep[to[i]]!=dep[x]+1 || !cap[i])     continue;
int f=dfs(to[i],min(now,cap[i]));
now-=f;
c+=f;
cap[i]-=f;
cap[i^1]+=f;
if(!now)        break;
}
return c;
}
queue<int>q;
int bfs(){
memset(dep,0,sizeof(dep));
q.push(s);dep[s]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=nex[i]){
if(cap[i] && !dep[to[i]]){
dep[to[i]]=dep[x]+1;
q.push(to[i]);
}
}
}
return dep[t];
}
inline int Dinic(){
int c=0;
while(bfs()){
for(int i=1;i<=n*m;++i)      fir[i]=head[i];
c+=dfs(s,INF);
}
return c;
}
int main(){
init();
printf("%d",Dinic());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: