【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%:对于每一条边统计 有 ...
随机推荐
- Java调用WebService方法总结(5)--Axis2调用WebService
Axis2是新一点Axis,基于新的体系结构进行了全新编写,有更强的灵活性并可扩展到新的体系结构.文中demo所使用到的软件版本:Java 1.8.0_191.Axis2 1.7.9. 1.准备 参考 ...
- Throw 和Throws 的区别
throw语句用在方法体内,表示抛出异常,由方法体内的语句处理.throws语句用在方法声明后面,表示再抛出异常,由该方法的调用者来处理. 和在service中处理异常的方式差不多,并没有什么特别新奇 ...
- 纯 CSS 画 iphone
好几天没有更新了,直接上效果吧,哈哈!(我想这个应该大部分都会!哈哈哈!) 代码如下: html: <div class="container"> <div cl ...
- Ane技术大全 - Devil程序员
来源:http://www.th7.cn/Program/Android/201405/206863.shtml 一.Ane概况 1.Ane是什么? Ane是为了解决 as3(flash)与Java代 ...
- SpringBoot学习<一>——快速搭建SpringBoot
这是我的第一篇博客,博客记录我以后的学习,包括一些总结之类的东西,当然,这些记录是针对于与我个人而言的,可能有些地方会有不好的,或者出现错误,欢迎大家来指正(如果有人看的话)废话不多说.进入正题:Sp ...
- C#中hashtable如何嵌套遍历
嵌套hashtable的遍历取值怎么做 hastable中嵌套了hashtable,想用递归的方式把所有hashtable中的key和value取出来 foreach (DictionaryEntry ...
- LNMP - Warning: require(): open_basedir restriction in effect错误解决方法
LNMP 1.4或更高版本如果不想用防跨目录或者修改.user.ini的防跨目录的目录还需要将 /usr/local/nginx/conf/fastcgi.conf 里面的fastcgi_param ...
- php 加密
PHP 自带的加密解密函数 目前经常使用的加密函数有:md5(), sha1(), crypt(), base64_encode(), urlencode() .其中 md5(), sha1(), c ...
- 191016 Linux中安装python3
注意事项:直接在Linux系统中安装python3后会导致yum命令和pip命令失效. 安装python3过程(按下述方法安装依赖包.指定软链接,就不会出错了): # 安装依赖包 yum instal ...
- 拖拉插件 drag drop
https://hejx.herokuapp.com/vue-dndl # Installation npm install vue-drag-and-drop-list --save # Usage ...