#include using namespace std; typedef pair 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 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 第一行三个正整数 n,m 和 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; }