dinic
代码来源是狼抓兔子
先跑出分层图然后流
有当前弧优化(这个和欧拉回路的操作很像?)
#include<bits/stdc++.h>
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define Ln inline
#define ll long long
using namespace std;
inline int rd(){
int f=0,x=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return f?-x:x;
}
const int N=2e3+3,inf=1e9;
struct Id{
int v,w,nt;
}e[N*N*6];
int p[N*N],id=1;
Ln void add(int x,int y,int z){
e[++id]={y,z,p[x]};
p[x]=id;
e[++id]={x,0,p[y]};
p[y]=id;
e[++id]={x,z,p[y]};
p[y]=id;
e[++id]={y,0,p[x]};
p[x]=id;
}
int dis[N*N],cur[N*N];
int n,m,s,t;
bool bfs(){
memset(dis,-1,sizeof(dis));
queue<int>q;
q.push(s);
dis[s]=0;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=p[x];i;i=e[i].nt){
int v=e[i].v;
if(dis[v]==-1&&e[i].w){
dis[v]=dis[x]+1;
q.push(v);
}
}
}
return dis[t]!=-1;
}
int dfs(int x,int sum){
if(x==t)return sum;
for(int i=cur[x];i&∑i=e[i].nt){
cur[x]=i;
int v=e[i].v;
if(e[i].w&&dis[v]==dis[x]+1){
int k=dfs(v,min(sum,e[i].w));
if(k){
e[i].w-=k;
e[i^1].w+=k;
return k;
}
else dis[v]=-1;
}
}
return 0;
}
int dinic(){
int ans=0,k;
while(bfs()){
memcpy(cur,p,sizeof(p));
while(k=dfs(s,inf))ans+=k;
}
return ans;
}
signed main(){
n=rd(),m=rd();
s=1,t=n*m;
F(i,1,n){
F(j,1,m-1){
int x=rd();
add((i-1)*m+j,(i-1)*m+j+1,x);
}
}
F(i,1,n-1){
F(j,1,m){
int x=rd();
add((i-1)*m+j,i*m+j,x);
}
}
F(i,1,n-1){
F(j,1,m-1){
int x=rd();
add((i-1)*m+j,i*m+j+1,x);
}
}
cout<<dinic();
return 0;
}

浙公网安备 33010602011771号