关于HLPP的一点问题
查看原帖
关于HLPP的一点问题
107186
fangbozhen楼主2020/6/9 15:01

以下代码RE80分,删除GAP优化后100分

#include<bits/stdc++.h>
using namespace std;

const int N = 1e3 + 10, M = 1e4 + 10;
const int INF = 0x3f3f3f3f;
int head[N], tot = -1, to[M], nxt[M], w[M];
void add_edge(int x, int y, int z) {
	nxt[++tot] = head[x]; head[x] = tot; to[tot] = y; w[tot] = z;
}
void add(int x, int y, int z) {
	add_edge(x, y, z); add_edge(y, x, 0);
}

int gap[N], ex[N], ht[N];
bool bfs_init(int s, int t) {
	memset(ht, 0x3f, sizeof(ht));
	queue<int> q;
	ht[t] = 0; q.push(t);
	while (!q.empty()) {
		int u = q.front(); q.pop();
		for (int i = head[u]; ~i; i = nxt[i]) {
			int v = to[i];
			if (w[i ^ 1] && ht[v] > ht[u] + 1)
				ht[v] = ht[u] + 1, q.push(v);
		}
	}
	return ht[s] != INF;
}

struct cmp {
	bool operator () (int a, int b) const {
		return ht[a] < ht[b];
	}
};
priority_queue<int, vector<int>, cmp> q;

bool exist[N];
bool push(int s, int t, int u) {
	for (int i = head[u]; ~i; i = nxt[i]) {
		int v = to[i], d;
		if (!w[i] || ht[u] != ht[v] + 1) continue ;
		d = min(w[i], ex[u]);
		ex[u] -= d; ex[v] += d; w[i] -= d; w[i ^ 1] += d;
		if (v != s && v != t && !exist[v])
			q.push(v), exist[v] = 1;
		if (!ex[u]) return 0;
	}
	return 1;
}

void relabel(int u) {
	ht[u] = INF;
	for (int i = head[u]; ~i; i = nxt[i])
		if (w[i]) ht[u] = min(ht[u], ht[to[i]]);
	ht[u]++;
}

int maxflow, cnt;
void HLPP(int s, int t) {
	if (!bfs_init(s, t)) {maxflow = 0; return ;}
	memset(ex, 0, sizeof(ex));
	memset(gap, 0, sizeof(gap));
	ht[s] = cnt;
	for (int i = 1; i <= cnt; i++)
		if (ht[i] != INF) gap[ht[i]]++;
	for (int i = head[s]; ~i; i = nxt[i]) {
		int v = to[i], d = w[i];
		if (!d) continue ;
		ex[s] -= d; ex[v] += d; w[i] -= d; w[i ^ 1] += d;
		if (v != s && v != t && !exist[v]) 
			q.push(v), exist[v] = 1;
	}
	while (!q.empty()) {
		int u = q.top(); q.pop();
		exist[u] = 0;
		while (push(s, t, u)) {
			if (!(--gap[ht[u]]))
				for (int i = 1; i <= cnt; i++)
					if (i != s && i != t && ht[i] > ht[u] && ht[i] < cnt + 1) ht[i] = cnt + 1;
			relabel(u);
			++gap[ht[u]];
		}
	}
	maxflow = ex[t];
}

int x[N], y[N];
int main() {
	memset(head, -1, sizeof(head));
	int n, m;
	scanf("%d%d", &n, &m);
	int S = 1, T = n;
	for (int i = 1; i <= m; i++) {
		int z;
		scanf("%d%d%d", &x[i], &y[i], &z);
		add(x[i], y[i], z);
	} 
	cnt = n;
	HLPP(S, T);
	printf("%d ", maxflow);
	memset(head, -1, sizeof(head));
	tot = -1;
	for (int i = 1; i <= m; i++) add(x[i], y[i], 1);
	HLPP(S, T);
	printf("%d\n", maxflow);
	return 0;
}
2020/6/9 15:01
加载中...