有一些间谍使用着大量不同的化名在A城活动,现在秘密警察机构需要你识别出来那些化名属于同一人,哪些化名不是。
由于经费匮乏,秘密警察机构提供给你的资料是从间谍居住区卖菜的阿呆那里搞来的。阿呆脑筋有点糊涂,他只能通过回忆一些零碎的事情来告诉你诸如:“化名p和化名q属于同一人”的事情。但阿呆和间谍们都很熟,你可以确信他提供的资料包含的信息是充分的,即不存在两个化名p和q,它们属于同一人,但根据阿呆的信息无法推断出p、q属于同一人这一事实。
输入格式:
第1行:两个用空格分开的整数n、m,1<=n<=2000,1<=m<=20000,表示共n个化名,阿呆提供了m条信息。
第2~n+1行:每行一个长度不超过20的字符串,表示一个化名,字符串中只包含大写或小写字母。
第n+2~n+m+1行:每行二个化名p、q,中间用一个空格分开,表示阿呆告诉你p、q属于同一人。
第n+m+2行:一个整数t,1<=t<=20000,表示秘密警察机构向你提出t个问题。
第n+m+3~n+m+2+t行:每行二个化名p、q,中间用一个空格分开,表示秘密警察询问你化名p、q是否属于同一人。
输出格式:
t行,依次对应输入文件中的t个问题。若对应问题中的两个化名属于同一人,输出“YES”,否则输出“NO”。
样例输入:(name.in)
5 2
a
b
c
d
e
a b
a c
2
a c
d e
样例输出:(name.out)
YES
NO
使用二叉查找树查找。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
type node=record t:string[20];l,r:longint;end;
var n,m,i,j,s,x,y,k:longint;
f:array[0..20000]of node;
father:array[0..20000]of longint;
t,a,b:string[50];
function get(x:longint):longint;
begin
if x=father[x] then exit(x)
else
begin
father[x]:=get(father[x]);
exit(father[x]);
end;
end;
procedure union(x,y:longint);
begin
father[get(x)]:=get(y);
end;
begin
assign(input,'name.in');reset(input);
assign(output,'name.out');rewrite(output);
readln(n,m);
for i:=1 to n do father[i]:=i;
for i:=1 to n do
begin
readln(f[i].t);
s:=1;
if i>1 then
while true do
begin
if f[i].t<f[s].t then
if f[s].l=0 then begin f[s].l:=i;break;end
else s:=f[s].l;
if f[i].t>f[s].t then
if f[s].r=0 then begin f[s].r:=i;break;end
else s:=f[s].r;
end;
end;
for i:=1 to m do
begin
readln(t);
a:=copy(t,1,pos(' ',t)-1);
b:=copy(t,pos(' ',t)+1,length(t));
s:=1;
while true do
begin
if a<f[s].t then s:=f[s].l;
if a>f[s].t then s:=f[s].r;
if a=f[s].t then begin x:=s;break;end;
end;
s:=1;
while true do
begin
if b<f[s].t then s:=f[s].l;
if b>f[s].t then s:=f[s].r;
if b=f[s].t then begin y:=s;break;end;
end;
union(x,y);
end;
readln(k);
for i:=1 to k do
begin
readln(t);
a:=copy(t,1,pos(' ',t)-1);
b:=copy(t,pos(' ',t)+1,length(t));
s:=1;
while true do
begin
if a<f[s].t then s:=f[s].l;
if a>f[s].t then s:=f[s].r;
if a=f[s].t then begin x:=s;break;end;
end;
s:=1;
while true do
begin
if b<f[s].t then s:=f[s].l;
if b>f[s].t then s:=f[s].r;
if b=f[s].t then begin y:=s;break;end;
end;
if get(x)=get(y) then writeln('YES') else writeln('NO');
end;
close(input);close(output);
end.