洛谷2814(nt数据题)

链接:https://www.luogu.com.cn/problem/P2814

输入格式

输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用 #name 的形式描写一组父子关系中的父亲的名字,用 +name 的形式描写一组父子关系中的儿子的名字;接下来用 ?name 的形式表示要求该人的最早的祖先;最后用单独的一个 $ 表示文件结束。

输出格式

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

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <unordered_map> 
 6 
 7 using namespace std;
 8 
 9 const int  N = 50010;
10 unordered_map<string,string> p;
11 
12 string find(string x)
13 {
14     if (p[x] != x) p[x] = find(p[x]);
15     return p[x];
16 }
17 
18 int main()
19 {
20     char n;
21     int pcnt = 0;
22     string fa;
23     while ((n = getchar()) != '$')
24     {
25         string name;
26         cin >> name;
27 
28         if (n == '#')
29         {
30             fa = name;
31             if (p[name] == "") p[name] = name;
32         }
33         else if (n == '+') p[name] = fa;
34         else
35         {
36             string fn = find(name);
37             cout << name << ' ' << fn << endl;
38         }
39         
40         while( getchar()!= '\n');
41     }
42     
43     return 0;
44 }

31行解释:由于他已经给出了我们每一个子节点的父亲节点,那么子节点就不需要进行初始化,只需要对给出的父亲节点初始化一下就好。而又因为前面给出的子节点可能为后面的父节点,所以我们需要对第一次出现的父节点初始化一下,而不需要对每一个父节点初始化,如果对每一个父节点均进行初始化,那么父节点的父节点则会被覆盖掉。

我们在并查集的初始化中是由于每一个节点都是有可能为父节点,所以要对每一个节点都初始化。

posted @ 2020-12-22 02:04  筱翼深凉  阅读(214)  评论(0)    收藏  举报