題目描述
凱凱的工廠正在有條不紊地生產一種神奇的零件,神奇的零件的生產過程自然也很神奇。工廠裏有 位工人,工人們從 編號。某些工人之間存在雙向的零件傳送帶。保證每兩名工人之間最多隻存在一條傳送帶。
如果 號工人想生產一個被加工到第 階段的零件,則所有與 號工人有傳送帶直接相連的工人,都需要生產一個被加工到第 階段的零件(但 號工人自己無需生產第 階段的零件)。
如果 號工人想生產一個被加工到第 階段的零件,則所有與 號工人有傳送帶直接相連的工人,都需要爲 號工人提供一個原材料。
軒軒是 號工人。現在給出 張工單,第 張工單表示編號爲 的工人想生產一個第 階段的零件。軒軒想知道對於每張工單,他是否需要給別人提供原材料。他知道聰明的你一定可以幫他計算出來!
輸入
第一行三個正整數 ,和 ,分別表示工人的數目、傳送帶的數目和工單的數目。
接下來 行,每行兩個正整數 和 ,表示編號爲 和 的工人之間存在一條零件傳輸帶。保證
接下來 行,每行兩個正整數 和 ,表示編號爲 的工人想生產一個第 階段的零件。
輸出
共 行,每行一個字符串 或者 。如果按照第 張工單生產,需要編號爲 的軒軒提供原材料,則在第 行輸出 ;否則在第 行輸出 。注意輸出不含引號。
輸入 #1
3 2 6
1 2
2 3
1 1
2 1
3 1
1 2
2 2
3 2
輸入 #2
5 5 5
1 2
2 3
3 4
4 5
1 5
1 1
1 2
1 3
1 4
1 5
輸出 #1
No
Yes
No
Yes
No
Yes
輸出 #2 複製
No
Yes
No
Yes
Yes
樣例解釋
詳情見洛谷
思路
假設
五個點,五條邊
1 2
2 3
3 4
4 5
5 2
求五號做第一階零件一號是否提供原材料————Yes
求五號做第二階零件一號是否提供原材料————No
求五號做第三階零件一號是否提供原材料————Yes
求五號做第四階零件一號是否提供原材料————No
五號做第一、三階零件一號需要提供原材料
而第二、四階零件一號則不需要提供原材料
也就是奇數需要偶數不需要
求四號做第二階零件一號是否提供原材料————Yes
求四號做第三階零件一號是否提供原材料————No
求四號做第四階零件一號是否提供原材料————Yes
求四號做第五階零件一號是否提供原材料————No
四號做第二、四階零件一號需要提供原材料
而第一、三階零件一號則不需要提供原材料
也就是偶數需要奇數不需要
通過以上假設
我們很容易想到求出一號到各點的奇數最短路和偶數最短路
然後就是這麼簡單
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int x, y, n, m, t, ti;
int h[1000250];
struct whw
{
int w, h;
}wh[1000250];
struct xy
{
int l, r;//l爲奇數最短路,r爲偶數最短路
}F[1000250];
void hw(int x, int y)
{wh[++ti] = (whw){y, h[x]};h[x] = ti;}
void SPFA()
{
memset(F, 0x3f3f, sizeof(F));
F[1].r = 0;
queue<int>sy;
sy.push(1);
while(sy.size())
{
x = sy.front();
sy.pop();
for(int i = h[x]; i; i = wh[i].h)
{
int to = wh[i].w;
int l = F[to].l, r = F[to].r;
F[to].l = min(F[to].l, F[x].r + 1);//從上一個節點推出這個節點的最短路
F[to].r = min(F[to].r, F[x].l + 1);
if(F[to].l != l || F[to].r != r)sy.push(to);//如果有改變
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &t);
for(int i = 1; i <= m; ++i)
{
scanf("%d%d", &x, &y);
hw(x, y);hw(y, x);//建圖
}
SPFA();
for(int i = 1; i <= t; i++)
{
scanf("%d%d", &x, &y);
if((y % 2 && F[x].l <= y)
|| (!(y % 2) && F[x].r <= y))printf("Yes\n");
else printf("No\n");
}
return 0;
}