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;
}
posted @   feuerwerk  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示