第三部分 數據結構 --第四章 圖論算法1388:家譜(gen)

1388:家譜(gen)

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2041 通過數: 1035
【題目描述】
現代的人對於本家族血統越來越感興趣,現在給出充足的父子關係,請你編寫程序找到某個人的最早的祖先。

【輸入】
由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係由二行組成,用#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


思路:字符串形式的並查集1.用map容器來寫並查集,把本人和祖先並的時候,這時候不能再找本人的祖先string yy = find(y)。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
map<string,string>p;//map去重
string find(string x){//查找所在集合根節點
	if(p[x] == x) return x;
	return p[x] = find(p[x]);
} 
void un(string x, string y)//並查集連接
{
	string xx = find(x);
	//string yy = find(y);//把本人和祖先並的時候,這時候不能再找本人的祖先
	if(xx != y) p[y] = xx;
}
int main(){
	string s;
	string t;
	string t1;
	string t2;
	while(cin >> s, s != "$"){
		if(s[0] == '#'){
			t = s.substr(1);
			if(p[t] == "")
			p[t] = t;
		}
		else if(s[0] == '+'){
			t1 = s.substr(1);
			un(t,t1);
		}
		else if(s[0] == '?')
		{
			t2 = s.substr(1);
			find(t2);
			cout << t2 <<" " << p[t2] << endl;
		}
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章