40分AC前4个点求助
查看原帖
40分AC前4个点求助
700558
williamwei楼主2024/7/9 15:35
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50 + 10;
const int maxn = 2500 + 10;
const int maxm = 1e4 + 10;
const int inf = 0x3f3f3f3f;
const int ninf = 0xcfcfcfcf;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
#define POSIN(x, y) (x >= 1 && x <= n && y >= 1 && y <= n)
int n, m, k, id, tot, sum, ans, S, T, head, tail, h[maxn], d[maxn], f[maxn], p[maxn], q[maxm], a[N][N], b[N][N], c[N][N];
bool vis[maxn], used[maxn][maxn];
struct Edge {
	int to, w1, w2, nxt;
} e[maxm];
void addedge(int u, int v, int w1, int w2) {
	e[tot] = { v, w1, w2, h[u] }; h[u] = tot++;
	e[tot] = { u, 0, -w2, h[v] }; h[v] = tot++;
}
bool bfs() {
	memset(d, 0xcf, sizeof(d));
	memset(vis, 0, sizeof(vis));
	head = tail = 0;
	q[tail++] = S; d[S] = 0;
	vis[S] = true; f[S] = inf;
	while (head < tail) {
		int u = q[head++]; vis[u] = false;
		for (int k = h[u]; ~k; k = e[k].nxt) if (e[k].w1) {
			int v = e[k].to, w = e[k].w2;
			if (d[v] < d[u] + w) {
				d[v] = d[u] + w; p[v] = k;
				f[v] = min(f[u], e[k].w1);
				if (!vis[v]) q[tail++] = v, vis[v] = true;
			}
		}
	} return d[T] != ninf;
}
int main() {
	memset(h, -1, sizeof(h)); 
	cin >> n >> m >> k; id = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
			cin >> a[i][j]; sum += a[i][j];
			if ((i ^ j) & 1) b[i][j] = 1;
			else if (i & 1) b[i][j] = 2;
		}
	while (k--) {
		int u, v; cin >> u >> v;
		used[u][v] = true;
	}
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
			if (used[i][j]) continue;
			c[i][j] = ++id;
			if (b[i][j] == 1) ++id;
		}
	T = id + 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
			if (used[i][j]) continue; id = c[i][j];
			if (b[i][j] == 1) {
				addedge(id, id + 1, 1, 0);
				for (int x = 0; x < 4; x++) {
					int nx = i + dx[x], ny = j + dy[x];
					if (!POSIN(nx, ny) || used[nx][ny]) continue;
					if (!b[nx][ny]) addedge(c[nx][ny], id, 1, a[i][j]);
					else addedge(id + 1, c[nx][ny], 1, 0);
				} ++id;
			} else if (!b[i][j]) addedge(1, id, 1, 0);
			else addedge(id, T, 1, 0);
		}
	addedge(S, 1, m, 0);
	while (bfs()) {
		for (int x = T; x != S; ) {
			int k = p[x];
			e[k].w1 -= f[T]; e[k ^ 1].w1 += f[T];
			x = e[k ^ 1].to;
		} ans += d[T] * f[T];
		if (d[T] < 0) break;
	} cout << sum - ans << '\n';
	return 0;
}

2024/7/9 15:35
加载中...