2019CSP-J T4 【加工零件】

Description

下载 _1_.png

Solutions

考虑使用 SPFA 来解题。

先整理出题意中包含的条件:

1 有 n 个点, m 条边(输入输出里面写了),q 个询问。
2 每一次询问中,会给 a_i 号点一个值 L 。
3 i 号点如果有一个值 L 且 L > 0,那么与它有边连接的点就都会有一个值 L-1 ,当 L=0 时,这个点就会被标记。
4 若 1 号点会被标记时,此询问就要输出 “Yes” ,否则输出 “No” 。

因为走到一号点有走了单数条边和双数条边两种情况,那么我们设 $ma_i$ 和 $mb_i$ 分别表示 $i$ 号点到 1 号点的走单数条边和走双数条边的最短路径长度,用 $SPFA$ 去求这些数(剪个枝,时间复杂度不高)。

然后对于每组提问,我们只需要先判断一下这个走的步数 $L$ :如果是单数,就与 $ma_i$ 比一下,如果小于 $ma_i$ ,那就肯定走不到,如果大于等于 $ma_i$ ,那就能走到。复数的话同理比较。

然后这道题就做完了,详见 代码 部分。

Code

1
#include<cmath>
2
#include<cstdio>
3
#include<cstring>
4
#include<iostream>
5
#include<algorithm>
6
using namespace std;
7
const int tp=1000000;
8
int n,m,q,len,tou,wei,an;
9
int last[100001],ma[100001],mb[100001];
10
struct nod{int to,next;}d[200001];
11
struct node{int x,s;}f[1000000];
12
bool bz[100001];
13
void jianbian(int x,int y)
14
{
15
	d[++len].to=y;
16
	d[len].next=last[x];
17
	last[x]=len;
18
}
19
void bfs(int a)
20
{
21
	tou=0,wei=1;
22
	f[tou].x=a;f[tou].s=0;
23
	while(tou!=wei)
24
	{
25
		for(int i=last[f[tou].x];i!=0;i=d[i].next)
26
		{
27
			if(f[tou].s%2==1)
28
			{
29
				if(mb[d[i].to]>f[tou].s+1)
30
				{
31
					mb[d[i].to]=f[tou].s+1;
32
					f[wei].x=d[i].to;
33
					f[wei].s=f[tou].s+1;
34
					wei=(wei+1)%tp;
35
				}
36
			}
37
			else
38
			{
39
				if(ma[d[i].to]>f[tou].s+1)
40
				{
41
					ma[d[i].to]=f[tou].s+1;
42
					f[wei].x=d[i].to;
43
					f[wei].s=f[tou].s+1;
44
					wei=(wei+1)%tp;
45
				}
46
			}
47
		}
48
		tou=(tou+1)%tp;
49
	}
50
}
51
int main()
52
{
53
	freopen("work.in","r",stdin);
54
	freopen("work.out","w",stdout);
55
	memset(ma,127/3,sizeof(ma));
56
	memset(mb,127/3,sizeof(mb));
57
	scanf("%d%d%d",&n,&m,&q);
58
	for(int i=1;i<=m;i++)
59
	{
60
		int u,v;
61
		scanf("%d%d",&u,&v);
62
		jianbian(u,v);
63
		jianbian(v,u);
64
	}
65
	bfs(1);
66
	for(int i=1;i<=q;i++)
67
	{
68
		int a,l;
69
		scanf("%d%d",&a,&l);
70
		if(ma[a]>700000000&&mb[a]>700000000)
71
		{
72
			printf("No\n");
73
		}
74
		else if(l%2==1)
75
		{
76
			if(ma[a]<=l)
77
			{
78
				printf("Yes\n");
79
			}
80
			else
81
			{
82
				printf("No\n");
83
			}
84
		}
85
		else
86
		{
87
			if(mb[a]<=l)
88
			{
89
				printf("Yes\n");
90
			}
91
			else
92
			{
93
				printf("No\n");
94
			}
95
		}
96
	}
97
	return 0;
98
}