ssl家谱 并查集
题目大意
现在给出一系列的的父子关系,输出找到某个人的最早的祖先。
分析
直接用并查集把同一家族的人放入一个集合就好了,但要用hash把名字储存起来(要想一个好的方法把字符串变成数字,这很重要!)
反思
并查集和hash都是很久之前学的,但没有复习,所以这题一打出来就低级错误不断,一直出错,以后一定要定期复习以前所学的东西!!!
谨记!
代码
<span style="font-size:10px;">var
father:array[0..100000] of longint;
s:array[0..60000] of longint;
h:array[0..60000] of string;
s1,s2:string;
i,j,k:longint;
n,m:longint;
long,p:longint;
c:char;
function find(v:longint):longint;
begin
if father[v]=0
then
exit(v)
else
begin
father[v]:=find(father[v]);
find:=father[v];
end;
end;
procedure union(x,y:longint);
var
i,j:longint;
begin
i:=find(x); j:=find(y);
father[j]:=i;
end;
function hash(x:string):longint;
var
i,j:longint;
begin
j:=0;
for i:=1 to ord(x[0]) do
j:=ord(x[i])*i+j;
j:=j mod p;
while (h[j]<>'') and (h[j]<>x) do
j:=(j+1) mod p;
exit(j);
end;
begin
readln(s1);
long:=0;
p:=60000;
while s1[1]<>'$' do
begin
if (s1[1]='#')
then
begin
delete(s1,1,1);
j:=hash(s1);
if s[j]=0
then
begin
long:=long+1;
h[j]:=s1;
s[j]:=long;
end;
j:=s[j];
end;
if s1[1]='+'
then
begin
delete(s1,1,1);
k:=hash(s1);
if s[k]=0
then
begin
long:=long+1;
h[k]:=s1;
s[k]:=long;
end;
k:=s[k];
union(j,k);
end;
if s1[1]='?'
then
begin
delete(s1,1,1);
k:=hash(s1);
if s[k]=0
then
begin
long:=long+1;
h[k]:=s1;
s[k]:=long;
end;
k:=s[k];
write(s1);
for i:=0 to 60000 do
if s[i]=find(k) then writeln(' ',h[i]);
end;
readln(s1);
end;
end.</span><span style="font-size:18px;">
</span>

浙公网安备 33010602011771号