题目描述

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)的更多相关文章

  1. 【CSP模拟赛】God knows (李超线段树)

    题面 CODE 稍微分析一下,发现把(i,pi)(i,p_i)(i,pi​)看做二维数点,就是求极长上升子序列的权值最小值. 直接李超线段树 #include <bits/stdc++.h> ...

  2. 【CSP模拟赛】避难向导(倍增lca&树的直径)

    耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...

  3. 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树

    [BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...

  4. [NOIP10.6模拟赛]2.equation题解--DFS序+线段树

    题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...

  5. CSP模拟赛游记

    时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...

  6. Bzoj3197/洛谷3296 [SDOI2013]刺客信条assassin(树的重心+树Hash+树形DP+KM)

    题面 Bzoj 洛谷 题解 (除了代码均摘自喻队的博客,可是他退役了) 首先固定一棵树,枚举另一棵树,显然另一棵树只有与这棵树同构才有可能产生贡献 如果固定的树以重心为根,那么另一棵树最多就只有重心为 ...

  7. 【CSP模拟赛】天才绅士少女助手克里斯蒂娜(线段树&读入优化&输出优化)

    题面描述 红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响.选取显像管的任意一个平面,一开始平面内有个n电子,初始速度分别为vi,定义飘升系数为 $$\sum_{1\leqsl ...

  8. 【CSP模拟赛】奇怪的队列(树状数组 &二分&贪心)

    题目描述 nodgd的粉丝太多了,每天都会有很多人排队要签名.  今天有n个人排队,每个人的身高都是一个整数,且互不相同.很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来.同时nod ...

  9. 【csp模拟赛6】树上统计-启发式合并,线段树合并

    30%:暴力 40%:枚举L,R从L~n枚举,R每增大一个,更新需要的边(bfs实现)60%:枚举每条边, 计算每条边的贡献另外20%的数据:枚举每条边,计算每条边的贡献100%:对于每一条边统计 有 ...

随机推荐

  1. python-django中的APPEND_SLASH实现

    关于django中的APPEND_SLASH APPEND_SLASH 它是啥? 看变量名大概能知道做什么,就是添加斜线,用路由系统那里. 路由文件,只写了路由关系代码 ...... urlpatte ...

  2. session 在PC端正常设置读取,在移动端无法正常读取

    一.背景 最近在做一个面向三端[H5.IOS.安卓]的短信验证码登录接口.发送短信验证码时,服务端通过 session 保存验证码的值.登录时,从 session 获取验证码和用户输入的验证码 相比较 ...

  3. python多线程爆破压缩包密码

    import zipfile from threading import Thread #多线程库 import optparse #选定字典或者文件 def extractFile(zfile,pa ...

  4. 如何使用jenkins部署maven父子工程

    最近使用jenkins自动部署项目时遇到一个问题,如果部署单个的maven工程,没有什么问题, 但是在部署maven创建的父子工程,如果只从svn或者git上拉取子工程源码时,会报找不到父 工程pom ...

  5. GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?

    一.GC如何判断一个对象为”垃圾”的java堆内存中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”.那么GC具体通过什么手段来 ...

  6. 使用gulp构建项目

    gulp.js作为一个前端构建工具,类似于webpack.Grountjs.rollupjs,不过相对于其他几种打包工具,gulp的使用更轻量,配置更简单,打包速度更快,今天不说他们几个的区别,也不说 ...

  7. python(open文件读取)

    一.open文件读取 1.open('file','mode')打开一个文件 file 要打开的文件名,需加路径(除非是在当前目录) mode 文件打开的模式 需要手动关闭close 2.with o ...

  8. 【转】C语言宏定义的几个坑和特殊用法

    总结一下C语言中宏的一些特殊用法和几个容易踩的坑.由于本文主要参考GCC文档,某些细节(如宏参数中的空格是否处理之类)在别的编译器可能有细微差别,请参考相应文档. 宏基础 宏仅仅是在C预处理阶段的一种 ...

  9. 2013.6.26 - OpenNER第六天

    今例会的时候看CRF,突然感觉到ANN模型可能没有问题了,问题出在评价函数,不能接过好就说好,或者说收敛方法有问题,并不是打得对就答得好.还有就是我们应该让他能够根据需要而自己产生问题,问我们,然后我 ...

  10. CentOS 7 修改时区例如上海时区

    Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...