CF1867F—构造最小同构树
有意思的问题。设原树为
手玩一下,不难发现,若子树
进一步地,假设我们已经知道了一颗最小的
这显然是最优解,对这个解进行任何的改动都会导致答案变差。
那么进一步研究,可以得出
则必然有
这里可以推出
那么怎么判断呢?很简单,我们将
可以先预处理出
时间复杂度怎么说,设单次判断时间复杂度为
进一步地,具体实现怎么办?显然我们需要对一棵同构树进行哈希。
哈希方法不同,比较常见的有基于素数的哈希,这里介绍一种常数较大但绝无冲突的办法。(毕竟会有人对着代码卡哈希函数)
我们可以使用一个集合作为哈希函数。显然一个树必然是由更小的树组合而来。我们可以考虑对原树中每一棵不同构树标号,并且它所对应的集合为它的儿子的编号集合(注意是可重有序集)。
如下:
#define ve vector<int>
map<ve ,int>h;
int id[N],n,t,cnt,num;
int get(ve &a){
if(h.find(a)!=h.end())return h[a];
int id=h.size();h[a]=id;
return id;
}
void dfs(int u,int fa){
ve a;a.clear();
for(auto v:g[u]){
if(v==fa)continue;
dfs(v,u);
a.push_back(id[v]);
}
sort(a.begin(),a.end());
id[u]=get(a);cnt=max(cnt,id[u]);
return ;
}
这样做常数是极大的,但总体时间复杂度没有影响。
然后我们考虑进行枚举拼凑这一步。先枚举
方案怎么输出?我们本身就记录了每一棵树的构成儿子,可以直接遍历这棵树,并且记录当前父亲编号进行输出。
注意最后如果搜不到,此时
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!