我是靠谱客的博主 单身心情,这篇文章主要介绍第四题,现在分享给大家,希望可以做个参考。

题目描述

 “尼伯龙根是一棵由n-1条高架路连起n 个地区的树,每一次Load,你都会重生在某一个地区。如果重生点是整个尼伯龙根的重心,也就是这个树的重心,那么你就能在最短时间内带诺诺逃脱啦。”
“对了,再给你一点方便咯,你可以选一条高架桥断掉,再连接另外两个地方,每次Load只能用一次技能,而又必须使整个它仍构成树形结构。你的Save点在这里,Load自然会恢复原始的尼伯龙根咯。” 

输入

第一行两个整数n,m,n意义如题,m表示路明非Load了m次。
接下来n-1行,每行两个整数x,y表示节点x,y之间存在一条边。
接下来m行,每行一个整数p,表示这次Load的重生地区。

输出

对于每一个询问,输出一行
如果可以则输出”YES”,否则输出”NO”(注意没有引号)

样例输入

复制代码
1
2
3
4
5
6
7
8
5 3 1 2 1 3 1 4 1 5 1 2 3

样例输出

复制代码
1
2
3
YES NO NO

数据范围限制

对于20%的数据 1<=n,m<=50
对于50%的数据 1<=n,m<=3000
对于100%的数据 1<=n,m<=200000
对于此题,只能说不是很难。要搞懂还是很容易的。就是先将这一棵树的重心求出来(找其中一个就好了).用这个点为根重新组装一棵树。我们知道,一棵树的重心的分支上的结点多不会超过N/2。所以,我们可以运用这一特点,当要将一架桥换掉的时候,他的下面结点的是一定不会超过N/2。我们只需要考虑他的上面结点。对于根,他的所有结点数都不会超过N/2,所以,当重组树的根节点不再根的最大结点数的分支中时,我们可以将最大分支直接连到当前根的位置上,这样可以保证剩下的那个边上的结点一定是最小的了;如果在最大结点数的分支中时,取次大的即可。如果剩下的那条边的结点数还是超过了N/2,那么就输出'NO',反之输出'YES'.


代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
var jl,s,g,a,f,x,y:array[1..400000] of longint; n,m,dian,i,p,ji,max,max2,jis,ans:longint; h:array[1..400000,1..100] of longint; bz,zhi:array[1..400000] of boolean; bo:boolean; procedure dg(k:longint); var i,p:longint; begin if k=12 then k:=k; for i:=1 to g[k] do begin p:=h[k,i]; if bz[p]=false then begin bz[p]:=true; dg(p); f[k]:=f[k]+f[p]; end; end; f[k]:=f[k]+1; end; procedure dg2(k:longint); var i,p,t,s:longint; begin s:=n-f[k]; if bo then exit; dec(s); for i:=1 to g[k] do begin p:=h[k,i]; if bz[p] then continue; if s<f[p] then s:=f[p]; end; if s<=n div 2 then begin bo:=true; dian:=k; exit; end else begin for i:=1 to g[k] do begin if bz[h[k,i]] then continue; bz[h[k,i]]:=true; dg2(h[k,i]); if bo then exit; end; end; end; procedure jilu(k:longint); var i,p:longint; begin zhi[k]:=true; for i:=1 to g[k] do begin p:=h[k,i]; if bz[p]=false then begin bz[p]:=true; jilu(p); end; end; end; begin assign(input,'h3.in'); assign(output,'h3.out'); reset(input); rewrite(output); read(n,m); for i:=1 to n-1 do begin read(x[i],y[i]); inc(g[x[i]]); h[x[i],g[x[i]]]:=y[i]; inc(g[y[i]]); h[y[i],g[y[i]]]:=x[i]; end; for i:=1 to m do read(a[i]); fillchar(bz,sizeof(bz),false); fillchar(f,sizeof(f),0); bz[x[1]]:=true; dg(x[1]); fillchar(bz,sizeof(bz),false); bo:=false; bz[x[1]]:=true; dg2(x[1]); fillchar(f,sizeof(f),0); fillchar(bz,sizeof(bz),false); bz[dian]:=true; dg(dian); for i:=1 to g[dian] do begin p:=h[dian,i]; if max<f[p] then begin max:=f[p]; ji:=p; jis:=i; end; end; fillchar(bz,sizeof(bz),false); fillchar(zhi,sizeof(zhi),false); bz[dian]:=true; bz[ji]:=true; ans:=1; jilu(ji); for i:=1 to g[dian] do if i<>jis then begin p:=h[dian,i]; if max2<f[p] then max2:=f[p]; end; for i:=1 to m do begin if a[i]=dian then begin writeln('YES'); continue; end; if (zhi[a[i]]) then begin if n-f[a[i]]-max2<=n div 2 then writeln('YES') else writeln('NO'); end else begin if n-f[a[i]]-max<=n div 2 then writeln('YES') else writeln('NO'); end; end; close(input); close(output); end.



最后

以上就是单身心情最近收集整理的关于第四题的全部内容,更多相关第四题内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部