https://www.luogu.com.cn/problem/P2814
题目背景
现代的人对于本家族血统越来越感兴趣。
题目描述
给出充足的父子关系,请你编写程序找到某个人的最早的祖先。
输入格式
输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用 #name
的形式描写一组父子关系中的父亲的名字,用 +name
的形式描写一组父子关系中的儿子的名字;接下来用 ?name
的形式表示要求该人的最早的祖先;最后用单独的一个 $
表示文件结束。
输出格式
按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式为:本人的名字 ++ 一个空格 ++ 祖先的名字 ++ 回车。
输入输出样例
输入 #1复制
#George +Rodney #Arthur +Gareth +Walter #Gareth +Edward ?Edward ?Walter ?Rodney ?Arthur $
输出 #1复制
Edward Arthur Walter Arthur Rodney George Arthur Arthur
说明/提示
规定每个人的名字都有且只有 66 个字符,而且首字母大写,且没有任意两个人的名字相同。最多可能有 10^3103 组父子关系,总人数最多可能达到 5 \times 10^45×104 人,家谱中的记载不超过 3030 代。
思路:并查集,不过这里开map统计每个人的父亲节点。注意string的默认是空串
#include<iostream>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5;
typedef long long LL;
map<string,string> p;
string find(string x)
{
if(x!=p[x])
p[x]=find(p[x]);
return p[x];
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
char op;string s,s1,s2;
while(cin>>op)
{
if(op=='$') break;
else if(op=='#')
{
cin>>s;
if(p[s]=="") p[s]=s;//map内初始化为空串
else p[s]=find(s);
}
else if(op=='+')
{
cin>>s1;p[s1]=find(s);
}
else if(op=='?')
{
cin>>s2;
cout<<s2<<' '<<find(s2)<<endl;
}
}
return 0;
}