家谱

题目背景

现代的人对于本家族血统越来越感兴趣。

题目描述

给出充足的父子关系,请你编写程序找到某个人的最早的祖先。

输入输出格式

输入格式:

输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用#name的形式描写一组父子关系中的父亲的名字,用+name的形式描写一组父子关系中的儿子的名字;接下来用?name的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。

输出格式:

按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。

输入输出样例

输入样例#1:
#George
+Rodney
#Arthur
+Gareth
+Walter
#Gareth
+Edward
?Edward
?Walter
?Rodney
?Arthur
$
输出样例#1:
Edward Arthur
Walter Arthur
Rodney George
Arthur Arthur

说明

规定每个人的名字都有且只有6个字符,而且首字母大写,且没有任意两个人的名字相同。最多可能有1000组父子关系,总人数最多可能达到50000人,家谱中的记载不超过30代。

思路

并查集;

代码实现

 1 #include<map>
 2 #include<string>
 3 #include<cstdio>
 4 #include<iostream>
 5 using namespace std;
 6 const int maxn=5e4+10;
 7 int n,f[maxn];
 8 map<string,int>v;
 9 map<int,string>u;
10 int find(int k){return f[k]==k?k:f[k]=find(f[k]);}
11 int main(){
12     int a;
13     char cn,ch[10];
14     while(1){
15         cn=getchar();
16         if(cn=='$') return 0;
17         scanf("%s\n",ch);
18         if(!v[ch]){v[ch]=++n;u[n]=ch;f[n]=n;}
19         if(cn=='#') a=f[v[ch]];
20         if(cn=='+') f[v[ch]]=a;
21         if(cn=='?'){
22             printf("%s ",ch);
23             cout<<u[find(v[ch])]<<endl;
24         }
25     }
26 }

 

posted @ 2017-08-24 15:50  J_william  阅读(335)  评论(1编辑  收藏  举报