家譜 並查集

2021-07-11 01:56:56 字數 2816 閱讀 2103

description

現代的人對於本家族血統越來越感興趣, 現在給出充足的父子關係, 請你編寫程式找到 某個人的最早的祖先。

input

輸入檔案由多行組成, 首先是一系列有關父子關係的描述, 其中每一組父子關係由二行 組成,用#name 的形式描寫一組父子關係中的父親的名字,用+name 的形式描寫一組父子關 系中的兒子的名字;接下來用?name 的形式表示要求該人的最早的祖先;最後用單獨的乙個 $表示檔案結束。規定每個人的名字都有且只有 6 個字元,而且首字母大寫,且沒有任意兩 個人的名字相同。最多可能有 1000 組父子關係,總人數最多可能達到 50000 人,家譜中的 記載不超過 30 代。

output

按照輸入檔案的要求順序,求出每乙個要找祖先的人的祖先,格式:本人的名字+乙個 空格+祖先的名字+回車。

sample input

#george

+rodney

#arthur

+gareth

+walter

#gareth

+edward

?edward

?walter

?rodney

?arthur

$sample output

edward arthur

walter arthur

rodney george

arthur arthur 

一看這題,只需求最早的祖先,那麼我們可以把有父子關係的一對和並即可。如果a是b的祖先,p[x]為x的祖先,那麼p[b]=a。

(自己好好想想吧,如果不會並查集的,在網上看看)。

我們可以把每個人編號。用hash表快速找出乙個人前面有沒有出現過即可。

標程:•const

•p1=150000;

•var

•h:array [0..p1] of string;

•h1:array [0..p1] of longint;

•f:array [1..60000] of string;  

•p:array [1..60000] of longint;  

•s:string;

•ch:char;

•x,y,k,i:longint;

•function hash(s:string):longint;

•var

• i:longint;

•begin

•hash:=0;

• for i:=1 to length(s) do

•   hash:=hash*4+ord(s[i]); 

••end;

••function fd(s:string):longint;

•var x:longint;

•begin

• x:=hash(s);

• while h[x]<>'' do

•  begin

•   if h[x]=s then exit(h1[x]);

•   inc(x);

•   if x>p1 then x:=0;

•  end;

• exit(0);

•end;

••procedure ins(s:string;a:longint);

• var i,x:longint;

•begin

•x:=hash(s);

•while h[x]<>'' do

• begin

•   inc(x);

•   if x>p1 then x:=0;

• end;

•h[x]:=s; h1[x]:=a;

•end;

••function find(x:longint):longint;

•var y,root,w:longint;

•begin

•y:=x;

•  while p[y]>0 do

•   y:=p[y];

•  root:=y;

•  y:=x;

•  while p[y]>0 do

•   begin

•    w:=p[y];

•    p[y]:=root;

•    y:=w;

•   end;

•  find:=root;

•end;

••procedure union(x,y:longint);

•var

• u,v:longint;

•begin

•u:=find(x);

•v:=find(y);

•p[v]:=u;

•end;

••begin

•for i:=1 to p1 do 

•begin h[i]:=''; h1[i]:=0; end;

•repeat

• readln(s);

• if s='$' then break;

• ch:=s[1]; delete(s,1,1);

• x:=fd(s);

• if x=0 then

•  begin inc(k); f[k]:=s; x:=k; ins(s,k); end;

• if ch='#' then

•   y:=x;

• if ch='+' then

•   union(y,x);

• if ch='?' then

•  begin

•   writeln(s,' ',f[find(x)]);

•  end;

•until 1=2;

•end.

家譜(並查集)

problem description 現代的人對於本家族血統越來越感興趣,現在給出充足的父子關係,請你編寫程式找到某個人的最早的祖先。input 輸入有多組資料,每組資料由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係由二行組成,用 name的形式描寫一組父子關係中的父親的名字,用 ...

並查集 家譜

現代的人對於本家族血統越來越感興趣。給出充足的父子關係,請你編寫程式找到某個人的最早的祖先。輸入由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係中父親只有一行,兒子可能有若干行,用 name的形式描寫一組父子關係中的父親的名字,用 name的形式描寫一組父子關係中的兒子的名字 接下來用...

並查集 家譜

現代的人對於本家族血統越來越感興趣,現在給出充足的父子關係,請你編寫程式找到 某個人的最早的祖先。輸入檔案由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係由二行 組成,用 name 的形式描寫一組父子關係中的父親的名字,用 name 的形式描寫一組父子關 系中的兒子的名字 接下來用?n...