洛谷 2814 家譜 並查集 解題報告

題目背景

現代的人對於本家族血統越來越感興趣。

題目描述

給出充足的父子關係,請你編寫程序找到某個人的最早的祖先。

輸入輸出格式

輸入格式:

輸入由多行組成,首先是一系列有關父子關係的描述,其中每一組父子關係中父親只有一行,兒子可能有若干行,用#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章