门芯仅AC on #1 ,码风良好,求助
查看原帖
门芯仅AC on #1 ,码风良好,求助
534562
liheyang123楼主2025/1/22 15:52

record

#include<bits/stdc++.h>
using namespace std;

inline int read(){
	int s = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9'){f = (ch == '-' ? -1 : f); ch = getchar();}
	while(ch >= '0' & ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	return s * f;
}

const int N = 2e5 + 10;
const int M = 4e6 + 10;
const int INF = 3e8 + 7;

const int dx[5] = {0, 0, 0, 1, -1};
const int dy[5] = {0, 1, -1, 0, 0};

int S, T;
int n, m, ans = 0;
int ver[M], head[N], nxt[M], val[M], idx, cur[N];
//ver  边的终点
//head 某个节点的第一条访问的边
//val  流量 nxt 下一条边 idx 边序号
//cur  当前弧优化 
void add(int u, int v, int w){
	ver[idx] = v, nxt[idx] = head[u], val[idx] = w;
	head[u] = idx++;
	head[idx] = u, nxt[idx] = head[v], val[idx] = 0;
	head[v] = idx++;
}

//计算点编号
int getid(int x, int y){
	return x * m - m + y; 
}

int d[N], q[N];

bool bfs(){
	int hh = 0, tt = 0;
	memset(d, -1, sizeof d);
	q[0] = S, d[S] = 0, cur[S] = head[S];
	while(hh <= tt){
		int x = q[hh++];
		for(int i = head[x]; ~i; i = nxt[i]){
			int y = ver[i];
			if(d[y] == -1 && val[i]){
				d[y] = d[x]+1;
				cur[y] = head[y];
				if(y == T) return 1;
				q[++tt] = y;
			}
		}
	}
	return 0;
}

int find(int u, int lim){
	if(u == T) return lim;
	int flow = 0;
	for(int i = cur[u]; ~i && flow < lim; i = nxt[i]){
		int y = ver[i];
		cur[u] = i;
		if(d[y] == d[u] + 1 && val[i]){
			int tmp = find(y, min(lim - flow, val[i]));
			if(!tmp) d[y] = -1;
			val[i] -= tmp;
			val[i ^ 1] += tmp;
			flow += tmp;
		}
	}
	return flow;
}

int dinic(){
	int res = 0, flow;
	while(bfs()) while(flow = find(S, INF)) res += flow;
	return res;
}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//以上全是板子,所以注释比较少
//###############################

int main(){
	memset(head, -1, sizeof(head));
	n = read(), m = read();
//超源、超汇
	S = 0, T = n * m + 1;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			int x = read();
			ans += x;
//对点染色,偶数点联向奇数点
			if((i + j) & 1) add(getid(i, j), T, x);
			else {
				add(S, getid(i, j), x);
				for(int k = 1; k <= 4; k++){
					int tx = i + dx[k], ty = j + dy[k];
					if(tx >= 1 && tx <= n && ty >= 1 && ty <= m)
						add(getid(i, j), getid(tx, ty), INF);
				}
			}
		}
	}
	cout<<ans - dinic();
	return 0;
}
2025/1/22 15:52
加载中...