【CSP-J】【圖論】【最短路】加工零件

題目描述

凱凱的工廠正在有條不紊地生產一種神奇的零件,神奇的零件的生產過程自然也很神奇。工廠裏有 nn 位工人,工人們從 1n1 \sim n 編號。某些工人之間存在雙向的零件傳送帶。保證每兩名工人之間最多隻存在一條傳送帶。

如果 xx 號工人想生產一個被加工到第 L(L>1)L (L \gt 1) 階段的零件,則所有與 xx 號工人有傳送帶直接相連的工人,都需要生產一個被加工到第 L1L - 1 階段的零件(但 xx 號工人自己無需生產第 L1L - 1階段的零件)。

如果 xx 號工人想生產一個被加工到第 11 階段的零件,則所有與 xx 號工人有傳送帶直接相連的工人,都需要爲 xx 號工人提供一個原材料。

軒軒是 11 號工人。現在給出 qq 張工單,第 ii 張工單表示編號爲 aia_i的工人想生產一個第 LiL_i 階段的零件。軒軒想知道對於每張工單,他是否需要給別人提供原材料。他知道聰明的你一定可以幫他計算出來!

輸入

第一行三個正整數 nnmmqq,分別表示工人的數目、傳送帶的數目和工單的數目。

接下來 mm 行,每行兩個正整數 uuvv,表示編號爲 uuvv 的工人之間存在一條零件傳輸帶。保證 uvu \neq v
接下來 qq 行,每行兩個正整數 aaLL,表示編號爲 aa 的工人想生產一個第 LL 階段的零件。

輸出

qq 行,每行一個字符串 YesYes 或者 NoNo。如果按照第 ii 張工單生產,需要編號爲 11 的軒軒提供原材料,則在第 ii 行輸出 YesYes;否則在第 ii 行輸出 NoNo。注意輸出不含引號。

輸入 #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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章