家谱 并查集 map

并查集和map

题目描述
给出充足的父子关系,请你编写程序找到某个人的最早的祖先。
输入格式
输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用 #name 的形式描写一组父子关系中的父亲的名字,用 +name 的形式描写一组父子关系中的儿子的名字;接下来用 ?name 的形式表示要求该人的最早的祖先;最后用单独的一个 $ 表示文件结束。
输出格式
按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式为:本人的名字 ++ 一个空格 ++ 祖先的名字 ++ 回车。
样例
输入
#George
+Rodney
#Arthur
+Gareth
+Walter
#Gareth
+Edward
?Edward
?Walter
?Rodney
?Arthur
$
输出
Edward Arthur
Walter Arthur
Rodney George
Arthur Arthur
题目分析
找自己的祖先->明显的并查集,但是又有所不同,因为我们平时学的并查集元素们都是以数字的形式出现,本题目的父亲,子代,祖先都是字符串,那我们就想到了用map<a1,a2>mp(其中a1是数组下标类型,a2是数组内容类型) 比如在这个题目中我们可以map<string,string>mp(eg.mp[Edward]=Arthur;)
之后的做法和普通并查集是一样的

#include<bits/stdc++.h>
using namespace std;
map<string,string>mp;
//map数组用来记录string1的祖先string2是谁 
char s1;
string s2,sfa;
int i,j,n,m,l,k;
string find(string n)
{
	if(mp[n]==n)
	return n;
	return mp[n]=find(mp[n]);
}
int main()
{
	while(cin>>s1)
	{
		if(s1=='$')
		return 0;//结束条件
		cin>>s2;
		if(s1=='#')
		/*来了一个爸爸*/
		{
			if(mp[s2]=="")
			/*如果这位爸爸是第一次出现,
			他自己就是自己的爸爸 */ 
			mp[s2]=s2;
			else
			/*否则,要找他的祖先,因为s2
			有一种可能在之前是别人的儿子,
			所以你需要用find函数找到s2的祖先*/ 
			mp[s2]=find(s2);
			sfa=s2;
			/*为后来的+做准备,爸爸出现后
			再出现的+就是sfa的儿子*/ 
		}
		else if(s1=='+')
			mp[s2]=find(sfa);
			/*find(sfa)保险起见,
			我们找的是祖先的爸爸
			而不是直接让mp[s2]=sfa; 
			*/ 
		else if(s1=='?')
		cout<<s2<<" "<<find(mp[s2])<<endl;
		
	}
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值