P3556 题解
前言
最短路应用。内容抄自某校课件。
思路
首先想到题目与最短路有关。
假如
-
如果
和 同奇偶,且 ,那么这个长度为 的路径一定存在。因为可以从
走 步到 ,然后走两步在 与它相邻的点左右横跳,直到走的步数为 。 -
但是如果
与 不同奇偶,路径就一定不存在吗?
考虑下面的情况:
随便两个点,奇偶的路径都是合法的。
那么容易想到,我们可以维护从
然后我们根据
于是这题就差不多结束了。
但是还有一组恶心的特判:
3 1 1
1 2
3 3 2
如果一个点是孤立的,那么怎么走都无解!
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int N = 5005, K = 1e6 + 5;
struct Edge {int now, nxt;} e[N << 1];
int head[N], cur;
void add(int u, int v)
{
e[++cur].now = v, e[cur].nxt = head[u];
head[u] = cur;
}
int dis[N][2]; //分奇偶
bool inque[N];
void spfa(int s)
{
memset(dis, 0x3f, sizeof dis);
memset(inque, false, sizeof inque);
queue <int> q;
q.push(s), inque[s] = true, dis[s][0] = 0;
while (!q.empty())
{
int u = q.front();
q.pop(), inque[u] = false;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].now;
if (dis[u][0] + 1 < dis[v][1])
{
dis[v][1] = dis[u][0] + 1;
if (!inque[v]) inque[v] = true, q.push(v);
}
if (dis[u][1] + 1 < dis[v][0])
{
dis[v][0] = dis[u][1] + 1;
if (!inque[v]) inque[v] = true, q.push(v);
}
}
}
}
struct Query {int id, v, w;};
vector <Query> query[N];
bool ans[K];
int main()
{
//ios::sync_with_stdio(false);
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
while (m--)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v), add(v, u);
}
for (int i = 1; i <= k; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
query[u].push_back((Query){i, v, w});
}
for (int u = 1; u <= n; u++)
if (!query[u].empty() && head[u]) //特别注意!如果这个点是孤立的,怎么走都是无解
{
spfa(u);
for (Query t : query[u]) ans[t.id] = (t.w >= dis[t.v][t.w & 1]);
}
for (int i = 1; i <= k; i++)
if (ans[i]) puts("TAK"); else puts("NIE");
return 0;
}
希望能帮助到大家!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效