题目:
CodeForces - 1252F:Regular Forestation
题意:
给定一颗树,你需要找到一个点,移除这个点后,剩下的子树都是同构的
笔记:
判定树是否同构,有两种方法,一是树的最小表示法,二是树哈希,最小表示法的时间空间都比较大,数据小时适用
有根树的最小表示法:
对树跑一遍括号序列,叶子节点的括号序列就是“()”,非叶子节点,先对儿子节点的括号序列从小到大排序,它的括号序列就是“(son1son2son3)”,排序就是为了让子树绕着父亲节点旋转
如果是无根树,可以先找到这颗树的重心,把重心当作根跑一遍最小表示法即可;而树的重心可能有两个,而以两个不同的重心跑出来的最小表示法可能不一样,所以就要以两个重心为根跑两边
分析:
(1)这个题先跑一遍树形dp找到那个可移除的点,移除这个点后剩下的子树的 size 都是一样的,所以这个点一定是唯一的,然后就判断剩下的子树是否同构即可
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+15;
struct edge{
int to,nxt;
}e[maxn<<1];
int n,u,v,cnt,head[maxn],d[maxn];
inline void add(int u,int v){
e[++cnt] = (edge){v,head[u]};
head[u] = cnt;
}
int dp[maxn],root,sz;
void dfs(int x,int fa){
int sum = -1; dp[x] = 1; bool flag = true;
for(int i = head[x]; i > 0