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>