AcWing 1253. 家谱
原题链接
简单
作者:
Lupinus
,
2021-05-28 14:53:54
,
所有人可见
,
阅读 287
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <utility>
using namespace std;
const int maxn = 2e5;
/*
改进方向:把map换成unordered_map,没必要用vector
*/
map<string, int> name2no;
vector<string> names;
int p[maxn];
int top;
// 插入后返回新位置或者返回已存在的位置
int ins_once(string name) {
auto iter = name2no.find(name);
if (iter == name2no.end()) {
name2no.insert(make_pair(name, top));
names.push_back(name);
top++;
return top - 1;
}
return iter->second;
}
int find(int x) {
while (x != p[x]) {
x = p[x];
}
return x;
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
// 预留空间
names.reserve(maxn);
// 初始化并查集
for (int i = 0; i < maxn; ++i) p[i] = i;
string s;
int fa = -1;
int kid = -1;
bool flag = true;
while (flag) {
cin >> s;
switch (s[0]) {
case '#':
fa = ins_once(s.substr(1));
break;
case '+':
kid = ins_once(s.substr(1));
p[kid] = fa;
break;
case '?':
kid = name2no[s.substr(1)];
fa = find(kid);
cout << names[kid] << ' ' << names[fa] << endl;
break;
case '$':
flag = false;
break;
}
}
return 0;
}