SPFA+BFS 题解
众所周知,SPFA
他死了。
但是这道题目真的不能用 SPFA
吗?
确实!
首先我们来说一下 SPFA
,正常我们用 queue
进行 SPFA
,这是我们照常的习惯。但是其实不光光用 queue
可以实现,用其他 STL
容器也可以。试过 vector
,比 queue
好,但是还是 T
了不少。但是其实 priority_queue
会强很多,至于是按什么排序其实都可以,我是用 less<int>
的。
SPFA
开了 priority_queue
优化仍然会 T
一个点,大概率是大数据卡掉了 SPFA
。
那怎么办呢?很简单。这题本质考的是 BFS
,那么按数据分析,BFS
(其实 Subtask 1 和 Subtask 4 中 n 都是 1000)。不然就用 SPFA
。
另外,对于这道题优先队列优化 BFS
也适用。
代码(开 O2
后 AC
):
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现