【并查集】家谱

匿名 (未验证) 提交于 2019-12-02 23:34:01

家谱

题目

现代的人对于本家族血统越来越感兴趣, 现在给出充足的父子关系, 请你编写程序找到 某个人的最早的祖先。

输入

输入文件由多行组成, 首先是一系列有关父子关系的描述, 其中每一组父子关系由二行 组成,用#name 的形式描写一组父子关系中的父亲的名字,用+name 的形式描写一组父子关 系中的儿子的名字;接下来用?name 的形式表示要求该人的最早的祖先;最后用单独的一个 $表示文件结束。规定每个人的名字都有且只有 6 个字符,而且首字母大写,且没有任意两 个人的名字相同。最多可能有 1000 组父子关系,总人数最多可能达到 50000 人,家谱中的 记载不超过 30 代。

输出

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

输入样例#George

+Rodney #Arthur +Gareth +Walter #Gareth +Edward ?Edward ?Walter ?Rodney ?Arthur $

输出样例

Edward Arthur Walter Arthur Rodney George Arthur Arthur 

解题思路

其实就是用并查集来连接父子节点,然后统计即可.

程序如下

#include<iostream> #include<algorithm> #include<cstdio> #include<map> using namespace std; char s; string t,q; map<string,string>a; string find(string dep)//并查集 { 	if(a[dep]=="") 		return dep; 	else  	   return a[dep]=find(a[dep]); } char sr() { 	char x; 	cin>>x; 	while(x==' '||x=='\n') //判断是否为下一行 	   cin>>x; 	return x; } int main() { 	s=sr(); 	while(s!='$') 	{ 		cin>>t; 		if(s=='#')  		{ 			while((s=sr())=='+') //如果是+号就加子节点 			{ 				cin>>q; 				a[find(q)]=find(t);   			}  		}  		else if(s=='?')  	    { 	    	 cout<<t<<' '<<find(t)<<endl; //输出 	    	 s=sr(); 	    }     } } 
转载请标明出处:【并查集】家谱
文章来源: https://blog.csdn.net/CWH2018/article/details/90301057
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!