题目详情
题目分析:
- 这一题没听课,自己写的,按理说数据结构不应该用封装好的
STL
, 但还是想自己尝试一下,结果导致答案非常短… - 这一题我用到了并查集,自认为并查集也算是一种树…
- 主要思路就是,先读入数据,用map的
键
存节点数据,值
存父节点的数据,题目保证每个结点中存储的字母是不同的,所以所有的键都不重复。没有子节点的节点一定是叶子,所以我的方法是找到所有的叶子,然后一直递归找到根节点,把每个叶子到根节点的数据连在一起,我们会得到所有叶子到根的路径,最后比较两个树的路径是否一致,一致则同构,不一致则输出No
#include <map>
#include <set>
#include <cstdio>
#include <string>
using namespace std;
string str;
map<char, char> m, mm;
multiset<string> s, ss;
int n;
char ch[2222], num1[2222], num2[2222];
void findroot(map<char, char> m, char q)
{
m[q] != q ? findroot(m, m[q]), str += q: str += q;//并查集核心算法,递归找到根节点,并把数据连在一起
}
void BuildTree(map<char, char> &m, multiset<string> &s)
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("\n%c %c %c", &ch[i], &num1[i], &num2[i]);//注意格式化输入
for (int i = 0; i < n; i++)
{
if (num1[i] != '-')
m[ch[num1[i] - '0']] = ch[i];//建树,给每个节点标上其父节点
if (num2[i] != '-')
m[ch[num2[i] - '0']] = ch[i];
}
for (char i = 0; i < n; i++)
if (num1[i] == '-' && num2[i] == '-')//找到叶子节点
{
findroot(m, ch[i]);
s.insert(str);//插入会自动按字典序排序
str = "";//查完每一条路径就清空
}
}
int main()
{
for (char i = 'A'; i <= 'Z'; i++)
mm[i] = m[i] = i;//初始化,一开始每个节点的根节点都是自己,互相独立
BuildTree(m, s);
BuildTree(mm, ss);
puts(s == ss ? "Yes" : "No");
}