#11 TLE * 2
查看原帖
#11 TLE * 2
448887
cancan123456楼主2021/8/6 13:55
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 105 
#define INF 2147483647
int n, m;
int a[maxn], b[maxn];
int c[maxn][maxn];
void input() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", a + i);
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d", b + i);
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%d", c[i] + j);
		}
	}
}
struct Edge {
	int v, flow, cost, next;
};
struct Graph {
	Edge edge[(maxn * maxn + 2 * maxn) * 2];
	int head[maxn * 2];
	int cnt;
	void __add_edge(int u, int v, int flow, int cost) {
		cnt++;
		edge[cnt].v = v;
		edge[cnt].flow = flow;
		edge[cnt].cost = cost;
		edge[cnt].next = head[u];
		head[u] = cnt;
	}
	void add_edge(int u, int v, int flow, int cost) {
		__add_edge(u, v, flow,  cost);
		__add_edge(v, u,    0, -cost);
	}
	int s, t;
	int min(int a, int b) {
		return a < b ? a : b;
	}
	int max_flow = 0, min_cost = 0;
	// 经过的总流量 
	int flow_[maxn];
	// 经过的总价格 
	int cost_[maxn];
	// 记录路径
	int pre[maxn];
	int last[maxn];
	bool inq[maxn];
	bool spfa() {
		memset(cost_, 0x3f, sizeof(cost_));
		cost_[s] = 0;
		queue < int > q;
		q.push(s);
		memset(inq, false, sizeof(inq));
		inq[s] = true;
		memset(flow_, 0, sizeof(flow_));
		flow_[s] = INF;
		while (!q.empty()) {
			int u = q.front(); q.pop();
			inq[u] = false;
			for (int i = head[u]; i; i = edge[i].next) {
				int v = edge[i].v, f = edge[i].flow, c = edge[i].cost;
				if (f > 0 && cost_[v] > cost_[u] + c) {
					cost_[v] = cost_[u] + c;
					flow_[v] = min(flow_[u], f);
					pre[v] = u;
					last[v] = i;
					if (!inq[v]) {
						q.push(v);
						inq[v] = true;
					}
				}
			}
		}
		return cost_[t] != 0x3f3f3f3f;
	}
	void mcmf() {
		while (spfa()) {
			max_flow += flow_[t];
			min_cost += flow_[t] * cost_[t];
			int now = t;
			while (now != s) {
				edge[last[now]].flow -= flow_[t];
				edge[last[now] ^ 1].flow += flow_[t];
				now = pre[now];
			}
		}
	}
	void init(bool smax) {
		int x = smax ? -1 : 1;
		cnt = 1;
		s = 0;
		t = n + m + 1;
		for (int i = 1; i <= n; i++) {
			add_edge(s, i, a[i], x * 0);
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				add_edge(i, j + n, INF, x * c[i][j]);
			}
		}
		for (int i = 1; i <= m; i++) {
			add_edge(i + n, t, b[i], x * 0);
		}
	}
} g1, g2;
signed main() {
	input();
	g1.init(false);
	g1.mcmf();
	g2.init(true);
	g2.mcmf();
	printf("%d\n%d", g1.min_cost, -g2.min_cost);
	return 0;
}

要加优化吗?

2021/8/6 13:55
加载中...