【CSP模拟赛】仔细的检查(树的重心&树hash)
题目描述
nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上。另一天nodgd更无聊,就又画了一张。
  这时nodgd发现,两次画的顺序是不一样的,这就导致了原本的某一个节点u0在第一幅图中编号为u1,在第二副图中编号为u2。
  于是,nodgd决定检查一下他画出的两棵树到底是不是一样的。nodgd已经给每棵树的节点都从1到n进行了编号,即每棵树有n个节点。
  如果存在一个1到n的排列p1,p2…pn,对于第一幅图中的任意一条边(i,j),在第二幅图中都能找到一条边(pi,pj),则认为这两幅图中的树是一样的。
输入格式
第一行一个整数n,表示节点的总数。
  接下来n−1行,每行两个整数,表示第一幅图中的每一条边。
  接下来n−1行,每行两个整数,表示第二幅图中的每一条边。
输出格式
如果两幅图的树是一样的,第一行输出”YES”,接下来1行输出一个1到n的排列p1,p2,……,pn,两个数之间用空格间隔。当多个排列都满足题意时,你可以随便输出一个。
  如果两幅图的树是不一样的,只输出一行”NO”。
  注意输出的时候不要加引号。
输入样例
3
  1 2
  2 3
  1 3
  3 2
输出样例
YES
  1 3 2
  提示
【样例解释1】
  肉眼可见,1-2-3和1-3-2显然是一样的两棵树。不过这可能不是唯一的符合题意的排列。
  数据范围:n<=100000
分析
正解好像是什么括号序列,被机房的大佬用树hash强行卡过了。。。。。。
对于一棵树,什么东西与它的根节点无关呢?
反正我知道的只有重心与直径
所以把重心找出来,直接树hash,再从根节点往下一一对应,判断子节点的对应点时用hash值给子节点排个序就好了
注意不能直接根据每个节点的hash值排序对应,因为如果有两棵子树结构相同,祖先子树结构不同时它们是无法被区分的。
好像这是我第一次写树的重心
另外此题hash也有技巧,有一篇论文《Hash在信息学竞赛中的一类应用》(反正我没看,只是用了他的hash方法)
代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=;
const unsigned long long seed=;
int n,cnt[],ans[maxn];
unsigned long long ha[][maxn];
vector<int>g[],son[][maxn];
int info[][maxn],nx[][maxn<<],v[][maxn<<];
void add(int u1,int v1,int k){nx[k][++cnt[k]]=info[k][u1];info[k][u1]=cnt[k];v[k][cnt[k]]=v1;}
bool cmp0(int a,int b){return ha[][a]<ha[][b];}bool cmp1(int a,int b){return ha[][a]<ha[][b];}
int yousa(int x,int f,int k)
{
int sz=,flag=;
for(int i=info[k][x],del;i;i=nx[k][i])if(v[k][i]!=f)
sz+=(del=yousa(v[k][i],x,k)),flag&=((del<<)<=n);
flag&=(((n-sz)<<)<=n);if(flag)g[k].push_back(x);
return sz;
}
void VR(int x,int f,int k)
{
son[k][x].clear();
for(int i=info[k][x];i;i=nx[k][i])
{
if(v[k][i]!=f)
VR(v[k][i],x,k),son[k][x].push_back(v[k][i]);
}
if(k==)sort(son[k][x].begin(),son[k][x].end(),cmp0);
if(k==)sort(son[k][x].begin(),son[k][x].end(),cmp1);
ha[k][x]=;
for(int i=son[k][x].size()-;i>=;i--)ha[k][x]=ha[k][x]*seed^ha[k][son[k][x][i]];
ha[k][x]*=seed*seed;
}
void solve(int a,int b){ans[a]=b;for(int i=son[][a].size()-;i>=;i--)solve(son[][a][i],son[][b][i]);}
int main()
{
scanf("%d",&n);
for(int k=;k<=;k++)for(int i=,u1,v1;i<n;i++)
scanf("%d%d",&u1,&v1),add(u1,v1,k),add(v1,u1,k);
yousa(,,);yousa(,,);
for(int i=,lim=g[].size();i<lim;i++)
{
VR(g[][i],,);
for(int j=,lim=g[].size();j<lim;j++)
{
VR(g[][j],,);
if(ha[][g[][i]]==ha[][g[][j]])
{
puts("YES");solve(g[][i],g[][j]);
for(int k=;k<=n;k++)printf("%d%c",ans[k],k==n?'\n':' ');
return ;
}
}
}
puts("NO");
}
【CSP模拟赛】仔细的检查(树的重心&树hash)的更多相关文章
- 【CSP模拟赛】God knows (李超线段树)
		
题面 CODE 稍微分析一下,发现把(i,pi)(i,p_i)(i,pi)看做二维数点,就是求极长上升子序列的权值最小值. 直接李超线段树 #include <bits/stdc++.h> ...
 - 【CSP模拟赛】避难向导(倍增lca&树的直径)
		
耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...
 - 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树
		
[BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...
 - [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
		
题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...
 - CSP模拟赛游记
		
时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...
 - Bzoj3197/洛谷3296 [SDOI2013]刺客信条assassin(树的重心+树Hash+树形DP+KM)
		
题面 Bzoj 洛谷 题解 (除了代码均摘自喻队的博客,可是他退役了) 首先固定一棵树,枚举另一棵树,显然另一棵树只有与这棵树同构才有可能产生贡献 如果固定的树以重心为根,那么另一棵树最多就只有重心为 ...
 - 【CSP模拟赛】天才绅士少女助手克里斯蒂娜(线段树&读入优化&输出优化)
		
题面描述 红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响.选取显像管的任意一个平面,一开始平面内有个n电子,初始速度分别为vi,定义飘升系数为 $$\sum_{1\leqsl ...
 - 【CSP模拟赛】奇怪的队列(树状数组 &二分&贪心)
		
题目描述 nodgd的粉丝太多了,每天都会有很多人排队要签名. 今天有n个人排队,每个人的身高都是一个整数,且互不相同.很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来.同时nod ...
 - 【csp模拟赛6】树上统计-启发式合并,线段树合并
		
30%:暴力 40%:枚举L,R从L~n枚举,R每增大一个,更新需要的边(bfs实现)60%:枚举每条边, 计算每条边的贡献另外20%的数据:枚举每条边,计算每条边的贡献100%:对于每一条边统计 有 ...
 
随机推荐
- MonoSymbolFileException in CheckLineNumberTable
			
Mono.CompilerServices.SymbolWriter.MonoSymbolFileException: Exception of type 'Mono.CompilerServices ...
 - HTML5的常用的标签
			
HTML5对比HTML4新增了很多元素,也删除了部分元素(可以用css样式表方式替代)所以我只列出HTML5最常用的几个标签. head标签中: <meta http-equiv="X ...
 - Appscan漏洞之Authentication Bypass Using HTTP Verb Tampering
			
本次针对 Appscan漏洞 Authentication Bypass Using HTTP Verb Tampering(HTTP动词篡改导致的认证旁路)进行总结,如下: 1. Authentic ...
 - 三步操作gitHub汉化插件安装--谷歌浏览器
			
如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人.谢谢大家!❤ 如果解决不了,可以在文末进群交流. 一个好用基于chrome的插件,用来汉化gitHub,大致效果图如下: 步骤一: 首先下载谷歌 ...
 - 1、uiautomator2常用语法
			
uiautomator2常用语法 连接设备 使用USB连接: d=u2.connect_USB('148b4090')输入手机序列号 d是给当前连接设备定位一个变量 获取设备的信息: print(d. ...
 - ansible之基础篇(二)
			
软件相关模块 yum rpm和yum的区别 rpm:redhat package manager yum 可以解决依赖关系 yum 源配置 使用yum下载时需要先下载epel [epel] name= ...
 - pod健康检查(liveness probe存活探针&&readiness probe 可读性探针)
			
在Kubernetes集群当中,我们可以通过配置liveness probe(存活探针)和readiness probe(可读性探针)来影响容器的生存周期.参考文档:https://kubernete ...
 - asp.net core 读取Appsettings.json 配置文件
			
Appsettingsjson 配置定义实体在StartUp时读取配置信息修改你的Controller通过构造函数进入配置信息总结Appsettings.json 配置很明显这个配置文件就是一个jso ...
 - SpringCloud_Eureka与Zookeeper对比
			
关系型数据库与非关系型数据库及其特性: RDBMS(Relational Database Management System 关系型数据库) :mysql/oracle/sqlServer等 = ...
 - unity 之协程返回值
			
yield return null; // 下一帧再执行后续代码yield return 6;//(任意数字) 下一帧再执行后续代码yield break; //直接结束该协程的后续操作yield r ...