求助,HLPP,TLE,64pts
查看原帖
求助,HLPP,TLE,64pts
213297
ttcwws楼主2022/1/20 00:24

rt

#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <forward_list>
#define N 1205
#define M 120005
#define IINF 0x3FFFFFFF
#define INF 0x3FFFFFFFFFFFFFFF
long long ex[N];
int h[N], gap[N], n, m, s, t, lv;
struct ed {int v, w, f;} gr[M << 1];
std::forward_list<int> mp[N], b[N];
int read()
{
	int x = 0;
	char c, f = 1;
	while (!isdigit(c = getchar()) && c != '-');
	if (c == '-')c = getchar(), f = -1;
	while (isdigit(c))
	{
		x = x * 10 + (c ^ '0');
		c = getchar();
	}
	return x * f;
}
bool bfs()
{
	std::queue<int> q;
	std::fill(h + 1, h + n + 1, IINF);
	q.push(t);
	h[t] = 0;
	while (!q.empty())
	{
		const int u = q.front();
		q.pop();
		for (const int i : mp[u])
		{
			const int& v = gr[i].v;
			if (gr[i ^ 1].w && h[v] > h[u] + 1)
				h[v] = h[u] + 1, q.push(v);
		}
	}
	return h[s] != IINF;
}
bool push(int u)
{
	for (const int& i : mp[u])
	{
		const int& v = gr[i].v, &w = gr[i].w;
		if (!w || (u != s && h[u] != h[v] + 1) || h[v] >= IINF)
			continue;
		long long k = std::min((long long)w, ex[u]);
		if (v != s && v != t && !ex[v])
			b[h[v]].push_front(v), lv = std::max(lv, h[v]);
		ex[u] -= k; ex[v] += k; gr[i].w -= k; gr[i ^ 1].w += k;
		if (!ex[u])return false;
	}
	return true;
}
void relabel(int u)
{
	h[u] = IINF;
	for (const int& i : mp[u])
	{
		const int& v = gr[i].v, &w = gr[i].w;
		if (w)h[u] = std::min(h[u], h[v]);
	}
	if (++h[u] < n)
	{
		b[h[u]].push_front(u);
		lv = std::max(lv, h[u]);
		++gap[h[u]];
	}
}
int selc()
{
	while (b[lv].empty() && lv >= 0)--lv;
	return lv >= 0 ? b[lv].front() : 0;
}
int main()
{
	int u;
	n = read(); m = read(); s = read(); t = read();
	for (int i = 1, t = 1, u, v, w; i <= m; ++i)
	{
		u = read(); v = read(); w = read();
		gr[++t] = {v, w};
		mp[u].push_front(t);
		gr[++t] = {u, 0};
		mp[v].push_front(t);
	}
	bfs();
	h[s] = n;
	ex[s] = INF;
	for (int i = 1; i <= n; ++i)
		if (h[i] < IINF)++gap[h[i]];
	push(s);
	while (u = selc())
	{
		b[lv].pop_front();
		if (push(u))
		{
			if (!--gap[h[u]])
				for (int i = 1; i <= n; ++i)
					if (i != s && i != t && h[i] > h[u] && h[i] <= n)
						h[i] = n + 1;
			relabel(u);
		}
	}
	printf("%lld", ex[t]);
}
2022/1/20 00:24
加载中...