悬关,求调
查看原帖
悬关,求调
989381
Great_Oak楼主2024/11/25 20:29
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
int s, t;
struct node {
	int to, nx, flow, cost;
} e[100005];
int h[100005];
int cc[1005][1005];
int tot = -1;
int pre[100005];//前驱
int cst[100005];//最小花费
int fl[100005];
int last[100005];//该点上一条边
int vis[100005];
void add_edge(int u, int v, int p, int c) {
	tot++;
	e[tot].to = v;
	e[tot].flow = p;
	e[tot].cost = c;
	e[tot].nx = h[u];
	h[u] = tot;
}
queue<int> q;
bool SPFA(int s, int t) {
	memset(cst, 127, sizeof(cst));
	memset(fl, 127, sizeof(pre));
	memset(vis, 0, sizeof(vis));
	vis[s] = 1;
	pre[t] = -1;
	//pre[s] = -1
	cst[s] = 0;
	q.push(s);
	while (!q.empty()) {
		int now = q.front();
		q.pop();
		cout<<now<<'\n';
		vis[now] = 0;
		for (int i = h[now]; i != -1; i = e[i].nx) {
		//	cout<<i<<'\n';
			if (e[i].flow > 0 && cst[e[i].to] > cst[now] + e[i].cost) {
				cst[e[i].to] = cst[now] + e[i].cost;
				pre[e[i].to] = now;
				last[e[i].to] = i;
				fl[e[i].to] = min(fl[now], e[i].flow);
				if (vis[e[i].to] == 0) {
					vis[e[i].to] = 1;
					q.push(e[i].to);
				}
			}
		}
	}
	return pre[t] != -1;
}
int inf = 0x7fffffffff;
int max_flow;
int min_cost;
int max_cost;
void solve_min() {
	while (SPFA(s, t)) {
		//	cout<<"*";
		int u = t;
		max_flow += fl[t];
		min_cost += fl[t] * cst[t];
		while (u != s) {
			e[last[u]].flow -= fl[t];
			e[last[u] ^ 1].flow += fl[t];
			u = pre[u];
		}
	}
}
void solve_max() {
	while (SPFA(s, t)) {
		int u = t;
	//	cout<<u;
		max_flow += fl[t];
		max_cost += fl[t] * cst[t];
		while (u != s) {
		//	cout<<u;
			e[last[u]].flow -= fl[t];
			e[last[u] ^ 1].flow += fl[t];
			u = pre[u];
		}
	}
}
int a[100005];
int b[100005];
signed main() {
	memset(h, -1, sizeof(h));
	cin  >> m >> n;
	/*
	for (int i = 1; i <= m; i++) {
		int u, v, w, c;
		cin >> u >> v >> w >> c;
		add_edge(u, v, w, c);
		add_edge(v, u, 0, -c);
	}
	*/
	s = 1;
	t = n + m + 2;
	for (int i = 1 + 1; i <= m + 1; i++) { //仓库 :1~m
		cin >> a[i];
		add_edge(s, i, a[i], 0);
		add_edge(i, s, 0, 0);
	}
	for (int i = 1 + m + 1; i <= n + m + 1; i++) { //零售商店 :m+1~n+m
		cin >> b[i];
		add_edge(i, t, b[i], 0);
		add_edge(t, i, 0, 0);
	}
	for (int i = 1 + 1; i <= m + 1; i++) { //仓库
		for (int j = 1 + m + 1; j <= n + m + 1; j++) { //零售商店
			int c;
			cin >> c;
			cc[i][j] = c;
			add_edge(i, j, inf, c);
			add_edge(i, j, 0, -c);
		}
	}
	solve_min();
	cout << min_cost;
	cout << '\n';
	max_flow = 0;
	tot = -1;
	memset(pre, 0, sizeof(pre));
	memset(last, 0, sizeof(last));
	memset(cst, 127, sizeof(cst));
	memset(e, 0, sizeof(e));
	memset(h, -1, sizeof(h));
	for (int i = 1 + 1; i <= m + 1; i++) { //仓库 :1~m
		add_edge(s, i, a[i], 0);
		add_edge(i, s, 0, 0);
	}
	for (int i = 1 + m + 1; i <= n + m + 1; i++) { //零售商店 :m+1~n+m
		add_edge(i, t, b[i], 0);
		add_edge(t, i, 0, 0);
	}
	for (int i = 1 + 1; i <= m + 1; i++) { //仓库
		for (int j = 1 + m + 1; j <= n + m + 1; j++) { //零售商店
			add_edge(i, j, inf, -cc[i][j]);
			add_edge(i, j, 0, cc[i][j]);
		}
	}
	solve_max();
	cout << - max_cost;
}
2024/11/25 20:29
加载中...