【Day2P1,无语的二分】化名 题解

      这是在郑州做的最简单的题目之一,可是我却悲剧地把二分打错了…My dear points~

 

 

【题目描述】
有一些间谍使用着大量不同的化名在A城活动,现在秘密警察机构需要你识别出来那些化名属于同一人,
哪些化名不是。
由于经费匮乏,秘密警察机构提供给你的资料是从间谍居住区卖菜的阿呆那里搞来的。阿呆脑筋有点糊
涂,他只能通过回忆一些零碎的事情来告诉你诸如:“化名p和化名q属于同一人”的事情。但阿呆和间谍们都
很熟,你可以确信他提供的资料包含的信息是充分的,即不存在两个化名p和q,它们属于同一人,但根据阿
呆的信息无法推断出p、q属于同一人这一事实。
【输入格式】
第1行:两个用空格分开的整数n、m,
1<=n<=20001<=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”。
【样例输入】
5 2
a
b
c
d
e
a b
a c
2
a c
d e
【样例输出】
YES
NO

 

      思路很简单,先将化名排序,然后利用二分查找(否则会有一个点不过)找到要进行合并的的化名的位置,并查集即可。只要基础代码不打错,100分还是很好得的~(不要像我一样打错二分什么的 /o\)

 

参考代码:

 

1 program names;
2 var
3 a:array[1..2000]of string;
4 n,m,i,j,k:longint;
5 x,y,p:longint;
6 s,st:string;
7 fa:array[1..2000]of longint;
8 function getfather(x:integer):integer; //找Father
9 begin
10 if fa[x]=x then exit(x);
11 fa[x]:=getfather(fa[x]);
12 getfather:=fa[x];
13 end;
14 procedure union(x,y:integer); //并查集
15 begin
16 x:=getfather(x);
17 y:=getfather(y);
18 if x<>y then fa[x]:=y;
19 end;
20 procedure find(x,y:integer); //查找,输出
21 begin
22 x:=getfather(x);
23 y:=getfather(y);
24 if x=y then writeln('YES')
25 else writeln('NO');
26 end;
27 procedure sort(l,r: longint); //按字典序快排,用来二分查找
28 var
29 i,j:longint;
30 x,y:string;
31 begin
32 i:=l;
33 j:=r;
34 x:=a[(l+r) div 2];
35 repeat
36 while a[i]<x do
37 inc(i);
38 while x<a[j] do
39 dec(j);
40 if not(i>j) then
41 begin
42 y:=a[i];
43 a[i]:=a[j];
44 a[j]:=y;
45 inc(i);
46 j:=j-1;
47 end;
48 until i>j;
49 if l<j then
50 sort(l,j);
51 if i<r then
52 sort(i,r);
53 end;
54 function getpos(x:string):longint; //二分查找
55 var
56 l,r:longint;
57 begin
58 l:=1;
59 r:=n;
60 getpos:=(l+r)div 2;
61 while x<>a[getpos] do
62 begin
63 if x>a[getpos] then begin
64 l:=getpos+1;
65 getpos:=(l+r)div 2;
66 end
67 else begin
68 r:=getpos;
69 getpos:=(l+r)div 2;
70 end;
71 end;
72 end;
73 begin
74 readln(n,m);
75 for i:=1 to n do
76 readln(a[i]);
77 sort(1,n);
78 for i:=1 to n do fa[i]:=i;
79 for i:=1 to m do
80 begin
81 readln(s);
82 p:=pos(' ',s);
83 st:=copy(s,1,p-1);
84 x:=getpos(st);
85 st:=copy(s,p+1,length(s)-p+1);
86 y:=getpos(st);
87 union(x,y);
88 end;
89 readln(k);
90 for i:=1 to k do
91 begin
92 readln(s);
93 p:=pos(' ',s);
94 st:=copy(s,1,p-1);
95 x:=getpos(st);
96 st:=copy(s,p+1,length(s)-p+1);
97 y:=getpos(st);
98 find(x,y);
99 end;
100 end.

 

 

(Saltless原创,转载请注明出处)

posted on 2010-10-09 17:01  saltless  阅读(233)  评论(0编辑  收藏  举报

导航