Symmetree
Symmetree
解题过程:
使用的是AHU算法实现树哈希,能够保证不会被卡,正确性十分强
刚刚现学的QAQ理解还没到位,但大概的思想还是懂了的
题面翻译
给定一棵树,\(1\) 为根。你可以调整一个点的儿子顺序,问这棵树是否有可能对称。
一棵树对称,如果根满足:
- 根最左边的儿子的子树与最右边的儿子的子树成镜像。
- 根左边第二个的儿子的子树与右边第二个儿子的子树成镜像。
........
- 如果儿子个数为奇数,那么中间的儿子的子树也满足对称。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N2 = 2e5 + 7;
int hs[N2], tot, is[N2];
vector<int> e[N2];
map<vector<int>, int> mp;
void dfs(int u = 1, int f = 0){
map<int, int> cnt;
vector<int> tmp;
for(auto v : e[u]){
if(v == f) continue;
dfs(v, u);
tmp.pb(hs[v]);
}
sort(tmp.begin(), tmp.end());
if(!mp[tmp]) mp[tmp] = ++ tot;
hs[u] = mp[tmp];
for(auto v : e[u]) if(v != f) ++ cnt[hs[v]];
int sum = 0, p;
for(auto [c, x] : cnt)
if(x & 1) ++ sum, p = c;
if(!sum) is[u] = 1;
else if(sum == 1)
for(auto v : e[u])
if(v != f && hs[v] == p) is[u] |= is[v];
}
void solve(){
int n;
cin >> n;
for(int i = 1;i <= n;i ++){
e[i].clear();
hs[i] = is[i] = 0;
}
mp.clear();
tot = 0;
for(int i = 1, u, v;i < n;i ++){
cin >> u >> v;
e[u].pb(v), e[v].pb(u);
}
dfs();
is[1] ? puts("YES") : puts("NO");
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T = 1;
cin >> T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号