写的 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;
}