You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
#define x first // 节点号
#define y second // 奇偶性
const int N = 100010, M = 200010;
int n, m, Q;
int h[N], e[M], ne[M], idx;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int dist[N][2]; // 奇偶最短路 dist[5][0]:4,dist[6][1]:3
queue<PII> q;
// ① 因边边权都是1不需要Dijkstra或者Floyd,只需要bfs即可
// ② 由于本题是强调 奇偶性 ,所以,需要使用 拆点 的思想
// ③ 所谓拆点就是像状态机或者DP中扩展维度的思想将奇偶点分开把混沌的事情清晰化。
// dist[i][0]:表示是偶数步的点,值是最小步数
// dist[i][1]:表示是奇数步的点
void bfs() {
memset(dist, 0x3f, sizeof dist); // 预求最短,先设最大
dist[1][0] = 0; // 1是起点0理解为从1号出发到1号结束走了0步的结果所以是偶数步步数为0
q.push({1, 0}); // 起点入队列
while (q.size()) {
auto u = q.front();
q.pop();
for (int i = h[u.x]; ~i; i = ne[i]) { // u点
PII v = {e[i], u.y ^ 1}; // 0 ^ 1 = 1 1 ^ 1 =0
if (dist[v.x][v.y] > dist[u.x][u.y] + 1) { // 如果利用u可以更新v这个点
dist[v.x][v.y] = dist[u.x][u.y] + 1; // 更新
q.push(v); // v的最短距离更新了入队列去更新更多的点
}
}
}
}
int main() {
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
memset(h, -1, sizeof h);
cin >> n >> m >> Q;
while (m--) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
bfs();
while (Q--) {
int a, l;
cin >> a >> l;
/*
如果不写下面的特判,会被欺负死:
3 1 1
2 3
1 2
第一行三个正整数 nm 和 q分别表示工人的数目、传送带的数目和工单的数目。
也就是3个工人1个传送带1个工单
传送带是2~3也就是1是与世隔绝的
接下来 q 行,每行两个正整数 a 和 L表示编号为 a 的工人想生产一个第 L 阶段的零件。
1号工人想生产2阶段的零件
由于1号工人是与世隔绝的没有人给它提供1阶段的零件肯定返回No,此时需要特判,返回答案
*/
if (h[1] == -1)
puts("No");
else if (l >= dist[a][l & 1]) // l是奇数并且大于奇数最短路则可以通过+2,+4,+6...等方法来回磨凑够l就完事
// l是偶数并且大于偶数最短路则可以通过+2,+4,+6...等方法来回磨凑够l就完事
puts("Yes");
else
puts("No");
}
return 0;
}