家谱(并查集)
来源:互联网 发布:安徵农业网络书屋 编辑:程序博客网 时间:2024/05/03 09:11
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;{HASH表,记录名字}
• h1:array [0..p1] of longint; {HASH表,记录编号}
• 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]);
• {哈希函数,这玩意贼神奇,一开始不乘4,超时!
• 乘个3,极限过!乘了4,直接15MS!!!!}
• 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); {找不到退出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; {找到空位x后记录数据}
• 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);{合并,x是父亲,y是儿子}
• var
• u,v:longint;
• begin
• u:=find(x);
• v:=find(y);
• p[v]:=u; {把儿子的祖先接到y上}
• 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); {s删掉第一个字符是人名}
• x:=fd(s); {查找}
• if x=0 then {找不到给当前人编号,并插入HASH表}
• 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)]);{查找x的最早的祖先,输出其姓名}
• end;
• until 1=2;
• end.
•
- 家谱(并查集)
- 家谱(并查集)
- ssl家谱 并查集
- 洛谷 2814 家谱 并查集 解题报告
- LuoguP2814 家谱 解题报告【并查集+map】
- 家谱 并差集
- 家谱
- 家谱
- 家谱
- 家谱
- 家谱
- HDU3938 并查集 并查集
- 并查集(集并查)
- HDU1232 并查集<并>
- 并查集
- 数据结构-并查集
- 并查集
- 并查集!
- Activity生命周期
- 码农小汪-Tomact使用war包发布项目
- 如何查看sqlserver中ddl操作记录的方法
- 关于vector大小(size)和容量(capacity)总结
- leetcode---Add Binary---string
- 家谱(并查集)
- Nearest Neighbor算法对Cifar-10数据集进行分类
- 2016中国VR行业预测研究报告
- 【English】Taoism,Follow AJ's System
- HDU4849-Wow! Such City!-dijkstra
- 树
- js 将json字符串转为js对象
- python 列表生成式
- 高光谱遥感图像处理(1)-----基础