直接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; }