MnZn刚学网络流1皮秒,求调
查看原帖
MnZn刚学网络流1皮秒,求调
343342
Obviathy楼主2023/4/10 12:01
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,M = 2e4+10,inf = 0x3f3f3f3f;
int n,m,s,t,op;
struct edge{
	int u,v,w,c,nxt;
}e[2*M];
int tot = -1,h[N];
int maxflow,mincost;
int flow[M];
int jo;
inline void add(int u,int v,int w,int c){
	if(!jo)swap(u,v);
	e[++tot].u = u;
	e[tot].v = v;
	e[tot].w = w;
	e[tot].c = c;
	e[tot].nxt = h[u];
	h[u] = tot;
	e[++tot].u = v;
	e[tot].v = u;
	e[tot].w = 0;
	e[tot].c = -c;
	e[tot].nxt = h[v];
	h[v] = tot;
} 
int d[N],vis[N],pre[N],realflow,ff[4] = {2,3,0,1};
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
inline int spfa(){
	memset(flow,0x7f,sizeof flow);
	memset(d,0x7f,sizeof d);
	memset(vis,0,sizeof vis);
	queue<int>q;
	d[s] = 0;
	vis[s] = 1;
	q.push(s);
	flow[s] = inf;
	pre[t] = -1;
	while(!q.empty()){
		int u = q.front();q.pop();
		vis[u] = 0;
		for(int i = h[u];i >= 0;i = e[i].nxt){
		//	cout << e[i].c <<endl;
			if(!e[i].w)continue;
			int v = e[i].v;
			if(d[v] > d[u] + e[i].c){
				d[v] = d[u] + e[i].c;
				flow[v] = min(flow[u],e[i].w);
				pre[v] = i;
				if(!vis[v]){
					q.push(v);
					vis[v] = 1;
				}
			}
		}
	}  
	return ~pre[t];
}
void MCMF(){
	while(spfa()){
		int x = t;
		mincost += d[t] * flow[t];
		maxflow += flow[t];
		int now;
		while(x != s){
			now = pre[x];
			e[now].w -= flow[t];
			e[now^1].w += flow[t];
			x = e[now^1].v;
		}
	}
}
inline int f(int i,int j,int w){return (i-1)*m+j+w*n*m;}
int main(){
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	s = 5*n*m+1;
	t = 5*n*m+2;
	memset(h,-1,sizeof h);
	for(int i = 1;i <= n;i ++){
		jo = i & 1;
		for(int j = 1;j <= m;j ++){
			cin >> op;
			jo ^= 1;
			if(jo){
				add(s,f(i,j,4),inf,0);
				for(int k = 0;k < 4;k ++){
					int x = i + dx[k],y = j + dy[k];
					if(x < 1 || x > n || y < 1 || y > m)continue;
					add(f(i,j,k),f(x,y,ff[k]),1,0);
				}
				for(int k = 0;k < 4;k ++){
					if(op & (1 << k)){
						add(f(i,j,4),f(i,j,k),1,0);
						++ realflow;
					}
				}
			}else{
				add(t,f(i,j,4),inf,0);
				for(int k = 0;k < 4;k ++){
					if(op & (1 << k)){
						add(f(i,j,4),f(i,j,k),1,0);
						++ realflow;
					}
				}
			}
			if(op == 8){
				add(f(i,j,3),f(i,j,0),1,1);
				add(f(i,j,3),f(i,j,2),1,1);
				add(f(i,j,3),f(i,j,1),1,2);
				continue;
			}
			if(op == 4){
				add(f(i,j,2),f(i,j,1),1,1);
				add(f(i,j,2),f(i,j,3),1,1);
				add(f(i,j,2),f(i,j,0),1,2);
				continue;
			}
			if(op == 2){
				add(f(i,j,1),f(i,j,0),1,1);
				add(f(i,j,1),f(i,j,2),1,1);
				add(f(i,j,1),f(i,j,3),1,2);
				continue;
			}
			if(op == 1){
				add(f(i,j,0),f(i,j,1),1,1);
				add(f(i,j,0),f(i,j,3),1,1);
				add(f(i,j,0),f(i,j,2),1,2);
				continue;
			}
			if(op == 3){
				add(f(i,j,1),f(i,j,3),1,1);
				add(f(i,j,0),f(i,j,2),1,1);
				continue;
			}
			if(op == 6){
				add(f(i,j,1),f(i,j,3),1,1);
				add(f(i,j,2),f(i,j,0),1,1);
				continue;
			}
			if(op == 9){
				add(f(i,j,3),f(i,j,1),1,1);
				add(f(i,j,0),f(i,j,2),1,1);
				continue;
			}
			if(op == 12){
				add(f(i,j,3),f(i,j,1),1,1);
				add(f(i,j,2),f(i,j,0),1,1);
				continue;
			}
			if(op == 7){
				add(f(i,j,0),f(i,j,3),1,1);
				add(f(i,j,2),f(i,j,3),1,1);
				add(f(i,j,1),f(i,j,3),1,2);
				continue;
			}
			if(op == 11){
				add(f(i,j,3),f(i,j,2),1,1);
				add(f(i,j,1),f(i,j,2),1,1);
				add(f(i,j,0),f(i,j,2),1,2);
				continue;
			}
			if(op == 13){
				add(f(i,j,0),f(i,j,1),1,1);
				add(f(i,j,2),f(i,j,1),1,1);
				add(f(i,j,3),f(i,j,1),1,2);
				continue;
			}
			if(op == 14){
				add(f(i,j,3),f(i,j,0),1,1);
				add(f(i,j,1),f(i,j,0),1,1);
				add(f(i,j,2),f(i,j,0),1,2);
				continue;
			}
		}
	}
	MCMF();
//	for(int i = 1;i <= tot;i ++)cout << e[i].c << endl;
//	cout << maxflow <<' ' << mincost << endl;
	if(maxflow*2==realflow)cout << mincost << endl;
	else cout << -1 << endl;
	return 0;
}

最常规的MCMF做法。

最大流求的没啥问题,但最小花费不对。

因为太弱了调不出来所以求助。谢谢

2023/4/10 12:01
加载中...