求助 SPFA + EK 63pts
查看原帖
求助 SPFA + EK 63pts
554746
yiming564楼主2024/4/18 00:00

使用 SPFA 和 EK 算法,但 #8 - #11 WA

测试 #8 程序输出:2938 608194

期望输出 2938 554237

求大佬指出代码中的错误

以及另一个问题,为什么 SPFA 不能使用 SLF 优化

#include <bits/extc++.h>

#define inline __always_inline

inline void read(int &x)
{
	char ch = getchar();
	while (!isdigit(ch))						ch = getchar();
	for (x = 0; isdigit(ch); ch = getchar())	x = x * 10 + ch - '0';
}

int n, m, s, t;
int u, v, w, c;

struct edge_t
{
	int64_t w, c;
	int to, next;
};
edge_t edge[100010];
int top = 2;
int head[5010], active[5010];
int depth[5010];

inline void add_edge(int u, int v, int64_t w, int64_t c)
{
	edge[top] = {w, c, v, head[u]};
	head[u] = top++;
	edge[top] = {0, -c, u, head[v]};
	head[v] = top++;
}

std::deque<int> queue;
char visit[5010];
int64_t dis[5010];
int last[5010];

inline void relax(int u, int v, int64_t c, int edge_it)
{
	if (dis[u] < dis[v] - c)
	{
		dis[v] = dis[u] + c;
		last[v] = edge_it;
		if (!visit[v])
		{
			visit[v] = 1;
			queue.push_back(v);
			// if (!queue.empty() && dis[v] < dis[queue.front()])
			// 	queue.push_front(v);
			// else
			// 	queue.push_back(v);
		}
	}
}

int64_t total_cost = 0;
int64_t total_flow = 0;

bool SPFA()
{
	memset(visit, 0, sizeof(visit));
	for (int i = 1; i <= n; i++)
		last[i] = -1;
	for (int i = 1; i <= n; i++)
		dis[i] = 0x7fffffffffffffff;
	dis[s] = 0;
	queue.clear();
	queue.push_back(s);
	while (!queue.empty())
	{
		auto u = queue.front();
		if (u == t)
			return true;
		visit[u] = 0;
		queue.pop_front();
		for (int v = head[u]; v != 0; v = edge[v].next)
			if (edge[v].w != 0)
				relax(u, edge[v].to, edge[v].c, v);
	}
	return false;
}

inline void Edmonds_Karp()
{
	while (SPFA())
	{
		int64_t subflow = 0x7fffffffffffffff;
		for (int i = t; i != s; i = edge[last[i] ^ 1].to)
			subflow = std::min(subflow, edge[last[i]].w);
		for (int i = t; i != s; i = edge[last[i] ^ 1].to)
		{
			total_cost += edge[last[i]].c * subflow;
			edge[last[i]].w -= subflow;
			edge[last[i] ^ 1].w += subflow;
		}
		total_flow += subflow;
	}
}

int main()
{
	freopen64("../P3381_8.in", "r", stdin);
	read(n), read(m), read(s), read(t);
	for (int i = 0; i < m; i++)
	{
		read(u), read(v), read(w), read(c);
		add_edge(u, v, w, c);
	}
	Edmonds_Karp();
	printf("%ld %ld", total_flow, total_cost);
	return 0;
}
2024/4/18 00:00
加载中...