直接dinic跑最大流可过
更新一下模板
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x))
using namespace std;
const int N=1000010,INF=1e9;
inline void read(int &d)
{
d=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){d=d*10+ch-'0';ch=getchar();}
}
struct Edge{
int to,nex,cap;
}edge[N<<3];
int n,m,head[N],tot,s,t;
queue<int> que;
inline void Add(int u,int v,int c)
{
edge[++tot].to=v;
edge[tot].nex=head[u];
edge[tot].cap=c;
head[u]=tot;
}
int dist[N],cur[N];
int dfs(int u,int maxf)
{
if(u==t||!maxf)return maxf;
int ret=0;
for(int &i=cur[u];i;i=edge[i].nex)
{
// cur[u]=i;
int v=edge[i].to,cap=edge[i].cap;
if(dist[v]==dist[u]+1&&cap>0){
int flow=dfs(v,min(maxf-ret,cap));
edge[i].cap-=flow;
edge[i^1].cap+=flow;
ret+=flow;
if(ret==maxf) break;
}
}
// if(!cur[u]) cur[u]=head[u];
if(!ret) dist[u]=-1;
return ret;
}
bool bfs()
{
clr(dist,60);dist[s]=0;que.push(s);
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=head[u];i;i=edge[i].nex)
{
int v=edge[i].to,cap=edge[i].cap;
if(dist[v]>INF&&cap>0){
dist[v]=dist[u]+1;
que.push(v);
}
}
}
return dist[t]<INF;
}
int dinic()
{
int ret=0,flow;
while(bfs()){
for(int i=s;i<=t;i++)cur[i]=head[i];
while(flow=dfs(s,INF))
ret+=flow;
}
return ret;
}
int main()
{
read(n);read(m);
//s=0;t=n*m+1;
s=1,t=n*m,tot=1;
int u,v;
//Add(s,1,INF+512);Add(n*m,t,INF+512);
for(int i=0,c;i<n;i++)
for(int j=1;j<m;j++)
{
read(c);u=i*m+j,v=i*m+j+1;
Add(u,v,c);Add(v,u,c);
}
for(int i=0,c;i<n-1;i++)
for(int j=1;j<=m;j++)
{
read(c);u=i*m+j,v=(i+1)*m+j;
Add(u,v,c);Add(v,u,c);
}
for(int i=0,c;i<n-1;i++)
for(int j=1;j<m;j++)
{
read(c);u=i*m+j,v=(i+1)*m+j+1;
Add(u,v,c);Add(v,u,c);
}
printf("%d",dinic());
return 0;
}