板子求调
查看原帖
板子求调
731925
happy_zero楼主2025/1/20 16:27

写的 spfa+dinic,样例 1 就没过(最大最小都不对),流量求的是对的费用错了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 205, M = 1e5 + 5;
const int INF = 1e9;
struct node { int nxt, to, w, c; } _e[M], e[M];
int ans, S, T, ecnt = 1, headt[N], head[N], _head[N];
void add(int u, int v, int w, int c) {
	_e[++ecnt] = {headt[u], v, w, c}, headt[u] = ecnt;
	_e[++ecnt] = {headt[v], u, 0, -c}, headt[v] = ecnt;
}
int dis[N], _dis[N];
bool vis[N];
queue <int> q;
bool spfa(int op) {
	memset(_dis, 0x3f, sizeof(_dis));
	memset(dis, 0, sizeof(dis));
	q.push(S), _dis[S] = 0, dis[S] = 1, vis[S] = true;
	while (!q.empty()) {
		int t = q.front(); q.pop(); vis[t] = false;
		for (int i = head[t]; i; i = e[i].nxt)
			if (e[i].w && _dis[e[i].to] > _dis[t] + e[i].c * op) {
				_dis[e[i].to] = _dis[t] + e[i].c * op;
				dis[e[i].to] = dis[t] + 1;
				if (!vis[e[i].to]) q.push(e[i].to), vis[e[i].to] = true;
			}
	}
	return dis[T];
}
int dfs(int now, int flow) {
	if (now == T) return flow; int sum = flow; 
	for (int &i = _head[now]; i; i = e[i].nxt)
		if (e[i].w && dis[e[i].to] == dis[now] + 1) {
			int t = dfs(e[i].to, min(flow, e[i].w));
			e[i].w -= t, e[i ^ 1].w += t, flow -= t, ans += t * e[i].c;
			if (!flow) break;
 		}
	if (sum == flow) dis[now] = 0; return sum - flow;
}
int dinic(int op) {
	memcpy(e, _e, sizeof(e)), memcpy(head, headt, sizeof(head)); ans = 0;
	while (spfa(op)) 
		memcpy(_head, head, sizeof(head)), dfs(S, INF);
	return ans;
}
signed main() {
	int n, m; cin >> n >> m; S = 0, T = n + m + 1;
	for (int i = 1, x; i <= n; i++)
		cin >> x, add(S, i, x, 0);
	for (int i = 1, x; i <= m; i++)
		cin >> x, add(i + n, T, x, 0);
	for (int i = 1; i <= n; i++)
		for (int j = 1, x; j <= m; j++)
			cin >> x, add(i, j + n, INF, x);
	cout << dinic(1) << '\n' << dinic(-1) << '\n';
	return 0;
}
2025/1/20 16:27
加载中...