标签:map cnt name fa int 题解 查集 P2814 家谱
一、理解与感悟
1、因为并查集需要编号,如果只给串的话,需要一个和数字的对应关系,用\(\_map\)保存这个关系。
2、最后还要输出祖先的姓名,就是一个根据数字获取名字的映射关系,用\(\_map2\)来保存这个关系。
二、完整代码
#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;
}
标签:map,cnt,name,fa,int,题解,查集,P2814,家谱 来源: https://www.cnblogs.com/littlehb/p/15118885.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。