SPFA 为什么不能使用 SLF 优化
查看原帖
SPFA 为什么不能使用 SLF 优化
554746
yiming564楼主2024/4/21 00:09

在我对 SPFA 使用了 SLF 优化之后,我喜提 #11 WA,这大抵就是出题人的毒瘤 hack 数据吧

但我很不理解,为什么 SPFA 不能使用 SLF 优化?为什么使用了就会在误判负环?

#include <bits/extc++.h>

#define inline						__always_inline
#define init_buf(l, r, buf, val)	for (auto m_it = l; m_it <= r; m_it++)	buf[m_it] = val
#define INF		1000000000l
#define cin		std::cin
#define cout	std::cout

template <typename key_t, typename cmp_fn>
using priority_queue = __gnu_pbds::priority_queue<key_t, cmp_fn>;
using pii = std::pair<int, int>;

int n, m;
int u, v, w;

struct edge_t
{
	int w;
	int v, tail;
};
edge_t edge[10000];
int head[3001], top = 1;
char visit[3001];

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

int h[3001];
void SPFA(int s = 0)
{
	int count[n + 1];
	init_buf(0, n, count, 0);
	init_buf(0, n, h, INF);	h[s] = 0;
	std::deque<int> queue;
	queue.push_back(s);
	while (!queue.empty())
	{
		auto u = queue.front();
		queue.pop_front();
		visit[u] = 0;
		for (int e = head[u]; e; e = edge[e].tail)
		{
			int v = edge[e].v, w = edge[e].w;
			if (h[v] - h[u] > w)
			{
				h[v] = h[u] + w;
				if (!visit[v])
				{
					visit[v] = 1;
					count[v]++;
					if (count[v] == n + 1)
						cout << "-1", exit(0);
					queue.push_back(v);
					// if (queue.empty() || h[v] < h[queue.front()])
					// 	queue.push_front(v);
					// else
					// 	queue.push_back(v);
				}
			}
		}
	}
	for (int u = 1; u <= n; u++)
		for (int e = head[u]; e; e = edge[e].tail)
			edge[e].w += h[u] - h[edge[e].v];
}

int dis[3001][3001];
priority_queue<pii, std::greater<pii>> pq;
decltype(pq)::point_iterator its[3001];

inline void Dijkstra(int s)
{
	int *row = dis[s];
	init_buf(1, n, row, INF);	row[s] = 0;
	init_buf(1, n, its, pq.push({row[m_it], m_it}));
	init_buf(1, n, visit, 0);
	while (!pq.empty())
	{
		auto u = pq.top().second;
		pq.pop();
		visit[u] = 1;
		for (int e = head[u]; e; e = edge[e].tail)
		{
			int v = edge[e].v, w = edge[e].w;
			if (!visit[v] && row[v] - row[u] > w)
			{
				row[v] = row[u] + w;
				pq.modify(its[v], {row[v], v});
			}
		}
	}
}

inline void print_graph()
{
	for (int u = 1; u <= n; u++)
	{
		cout << u << " | ";
		for (int e = head[u]; e; e = edge[e].tail)
			cout << '(' << edge[e].v << ", " << edge[e].w << ") ";
		cout << '\n';
	}
}

int main()
{
	cin.sync_with_stdio(false);
	cin.tie(NULL);
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		cin >> u >> v >> w;
		add_edge(u, v, w);
	}
	for (int i = 1; i <= n; i++)
		add_edge(0, i, 0);
	SPFA();
	for (int i = 1; i <= n; i++)
		Dijkstra(i);
	for (int u = 1; u <= n; u++)
	{
		int64_t ans = 0;
		for (int v = 1; v <= n; v++)
		{
			if (dis[u][v] == INF)
				ans += (int64_t)v * INF;
			else
				ans += (int64_t)v * (int64_t)(dis[u][v] - h[u] + h[v]);
		}
		cout << ans << '\n';
	}
	return 0;
}
2024/4/21 00:09
加载中...