'commit'
This commit is contained in:
58
TangDou/LuoGuBook/P2814.cpp
Normal file
58
TangDou/LuoGuBook/P2814.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string s, name;
|
||||
unordered_map<string, int> _map; //人员与编号的对应关系
|
||||
unordered_map<int, string> _map2;//编号与人名的对应关系
|
||||
int cnt, parentId, childId;
|
||||
|
||||
const int N = 200010;
|
||||
int fa[N]; //并查集数组
|
||||
|
||||
//要深入理解这个递归并压缩的过程
|
||||
int find(int x) {
|
||||
if (fa[x] != x) fa[x] = find(fa[x]);
|
||||
return fa[x];
|
||||
}
|
||||
|
||||
//合并并查集
|
||||
void join(int a, int b) {
|
||||
int x = find(a), y = find(b);
|
||||
if (x != y) fa[x] = y;
|
||||
}
|
||||
|
||||
int main() {
|
||||
//初始化并查集
|
||||
for (int i = 1; i <= N; i++) fa[i] = i;
|
||||
//不停的输入字符串
|
||||
while (cin >> s) {
|
||||
//结束标识
|
||||
if (s == "$") break;
|
||||
//叫啥
|
||||
name = s.substr(1);
|
||||
//检查首位
|
||||
if (s[0] == '#') {//父亲
|
||||
if (!_map[name]) {
|
||||
_map[name] = ++cnt;//分配一个号码
|
||||
_map2[cnt] = name; //反向记录号码对应的名字
|
||||
parentId = cnt;
|
||||
} else
|
||||
parentId = _map[name];
|
||||
} else if (s[0] == '+') {//儿子
|
||||
if (!_map[name]) {
|
||||
_map[name] = ++cnt;//分配一个号码
|
||||
_map2[cnt] = name; //反向记录号码对应的名字
|
||||
childId = cnt;
|
||||
} else
|
||||
childId = _map[name];
|
||||
//构建并查集
|
||||
join(childId, parentId);//注意顺序
|
||||
} else if (s[0] == '?') {//表示要求该人的最早的祖先
|
||||
childId = _map[name];
|
||||
//查询并查集
|
||||
cout << name << " " << _map2[find(childId)] << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user