万能的谷民
查看原帖
万能的谷民
253936
simonG楼主2023/5/6 09:42

dinic 加了当前弧,加了多路增广,还是 T 两个点

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
const int N=1e6+10,M=6e6+10;
const LL inf=1e18;
struct flow {
	int head[N],nxt[M],ver[M],limit[M],tot=1;
	void add(int u,int v,int w) {
		ver[++tot]=v; nxt[tot]=head[u]; head[u]=tot; limit[tot]=w;
		ver[++tot]=u; nxt[tot]=head[v]; head[v]=tot; limit[tot]=w;
	}
	int T,cur[N],dis[N];
	LL dfs(int u,LL res) {
		if(u==T) return res;
		LL flow=0;
		for(int i=cur[u]; i; i=nxt[i]) {
			cur[u]=i;
			int c=min(res,1LL*limit[i]),v=ver[i];
			if(dis[u]+1==dis[v]&&c) {
				int k=dfs(v,c);
				flow+=k; res-=k;
				limit[i]-=k; limit[i^1]+=k;
			}
		}
		if(!flow) dis[u]=-1;
		return flow;
	}
	LL maxflow(int s,int t) {
		T=t;
		LL flow=0;
		for(; ; ) {
			queue<int> Q;
			memcpy(cur,head,sizeof head);
			memset(dis,-1,sizeof dis);
			Q.push(s); dis[s]=0;
			for(; Q.size(); ) {
				int u=Q.front(); Q.pop();
				for(int i=head[u],v; i; i=nxt[i])
					if(dis[v=ver[i]]==-1&&limit[i])
						dis[v]=dis[u]+1,Q.push(v);
			}
			if(dis[t]==-1) return flow;
			flow+=dfs(s,inf);
		}
	}
} g;
int m,n,w;
int id(int i,int j) {return (i-1)*n+j;}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++)
		for(int j=1; j<m; j++) {
			scanf("%d",&w);
			g.add(id(i,j),id(i,j+1),w);
		}
	for(int i=1; i<n; i++)
		for(int j=1; j<=m; j++) {
			scanf("%d",&w);
			g.add(id(i,j),id(i+1,j),w);
		}
	for(int i=1; i<n; i++)
		for(int j=1; j<m; j++) {
			scanf("%d",&w);
			g.add(id(i,j),id(i+1,j+1),w);
		}
	printf("%lld\n",g.maxflow(id(1,1),id(n,m)));
	return 0;
}
2023/5/6 09:42
加载中...