SPFA+BFS 题解

众所周知,SPFA 他死了。

但是这道题目真的不能用 SPFA 吗?

确实!

首先我们来说一下 SPFA,正常我们用 queue 进行 SPFA,这是我们照常的习惯。但是其实不光光用 queue 可以实现,用其他 STL 容器也可以。试过 vector,比 queue 好,但是还是 T 了不少。但是其实 priority_queue 会强很多,至于是按什么排序其实都可以,我是用 less<int> 的。

SPFA(priority_queue) 测试

SPFA 开了 priority_queue 优化仍然会 T 一个点,大概率是大数据卡掉了 SPFA

那怎么办呢?很简单。这题本质考的是 BFS,那么按数据分析,n900n \ge 900BFS (其实 Subtask 1 和 Subtask 4 中 n 都是 1000)。不然就用 SPFA

另外,对于这道题优先队列优化 BFS 也适用。

代码(开 O2AC):

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

int n, m, q;
const int N = 1e3 + 5;
int dis[N];
int vec[N][N];
int ans[N][N];
bool vis[N], f[N], ansx[N][N];

struct ios_in // 快读
{
	inline char gc()
	{
		static char buf[N], * l, * r;
		return (l == r) && (r = (l = buf) + fread(buf, 1, N, stdin), l == r) ? EOF : *l++;
	}
	template <typename _Tp>
	inline ios_in& operator >> (_Tp& x) {
		static char ch, sgn;
		for (sgn = 0, ch = gc(); !isdigit(ch); ch = gc()) {
			if (!~ch) return *this;
			sgn |= ch == '-';
		}
		for (x = 0; isdigit(ch); ch = gc())
			x = (x << 1) + (x << 3) + (ch ^ '0');
		sgn && (x = -x);
		return *this;
	}
}Cin;

inline void spfa(int x) // spfa 模板
{
	priority_queue<int, vector<int>, less<int> > q; // 优先队列优化
	q.push(x);
	dis[x] = -1e7;
	while (q.size())
	{
		int l = q.top();
		q.pop();
		for (register int i = 1; i <= m; ++i)
		{
			int to = vec[i][l];
			if (dis[to] > dis[l] + 1)
			{
				dis[to] = dis[l] + 1;
				q.push(to);
			}
		}
	}
}

inline void bfs(int x) // bfs 模板
{
	priority_queue<int, vector<int>, less<int> > q;
	q.push(x);
	f[x] = true;
	vis[x] = true;
	while (q.size())
	{
		int l = q.top();
		q.pop();
		f[l] = true;
		for (register int i = 1; i <= m; ++i)
		{
			int to = vec[i][l];
			if (vis[to]) continue;
			q.push(to);
			vis[to] = true;
		}
	}
}

int main()
{
	Cin >> n;
	Cin >> m;
	Cin >> q;
	for (register int i = 1; i <= m; ++i)
	{
		for (register int j = 1; j <= n; ++j)
		{
			int x;
			Cin >> x;
			vec[i][j] = x; // 存储图
		}
	}
	if (n >= 900)
	{
		for (register int i = 1; i <= n; ++i)
		{
			memset(f, false, sizeof(f));
			memset(vis, false, sizeof(vis));
			bfs(i);
			for (register int j = 1; j <= n; ++j)
			{
				ansx[i][j] = f[j];
			}
		}
		while (q--)
		{
			int a, b;
			Cin >> a >> b;
			puts((!ansx[a][b] ? "NE" : "DA"));
		}
		return 0;
	}
	for (register int i = 1; i <= n; ++i)
	{
		memset(dis, 0, sizeof(dis));
		spfa(i);
		for (register int j = 1; j <= n; ++j)
		{
			ans[i][j] = dis[j];
		}
	}
	int a, b;
	while (q--)
	{
		Cin >> a;
		Cin >> b;
		puts((ans[a][b] == 0 ? "NE" : "DA"));
	}
	return 0;
}
posted @   HappyBobb  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示