題目背景
現代的人對於本家族血統越來越感興趣。
題目描述
給出充足的父子關係,請你編寫程序找到某個人的最早的祖先。
輸入輸出格式
輸入格式:
輸入由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係中父親只有一行,兒子可能有若干行,用#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代。
思路
這道題嘛。。。看標題就知道是並查集啊。。
但是這個是字符串版本的。。儘管沒啥子區別
那麼我們的函數什麼的相應的也就跟着變化了。這裏注意了,我用的map來維護兩者的關係而不是普通的並查集。
代碼
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
map<string,string> father;
char typ;
string getfather(string x)
{
if (x!=father[x]) father[x]=getfather(father[x]);
return father[x];
}
int main()
{
string f1,t;
while(true)
{
scanf("%c",&typ);
if (typ=='$') break;
if (typ=='#')
{
cin>>f1;
if (father[f1]=="") father[f1]=f1;
continue;
}
else if (typ=='+') {cin>>t;father[t]=f1;}
else if (typ=='?')
{
cin>>t;
cout<<t<<' '<<getfather(t)<<endl;
}
}
return 0;
}