JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查 树hash
Description
nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上。另一天nodgd更无聊,就又画了一张。
这时nodgd发现,两次画的顺序是不一样的,这就导致了原本的某一个节点u0在第一幅图中编号为u1,在第二副图中编号为u2。
于是,nodgd决定检查一下他画出的两棵树到底是不是一样的。nodgd已经给每棵树的节点都从1到n进行了编号,即每棵树n个节点。
如果存在一个1到n的排列p1p2…pn,对于第一幅图中的任意一条边(u,v),在第二幅图中都能找到一条边(pu,pv),则认为这两幅图中的树是一样的。
知道是树hash,但是从来没写过这个玩意儿,没有信心写出来,然后想了个水法只捞到10分。。
其实是树hash的模板题。。无根树转有根树是经典操作了,把重心当根,超过1个重心就直接新建一个点做为根,注意要把重心拉上去,重心之间的边显然不能走。然后处理完两棵树以后直接树hash,具体的话就是:
(((hash[x]*=base)^=tmp[i])+=tmp[i])^=tmp[i];
从下往上hash就可以了,注意base不能太小,最好不要模,冲突可能性比较大,还是自然溢出比较好,。
然后方案的话扫一遍用hash来映射就ok了。
一个小错误导致WA半天。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define mp make_pair
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
int n,m;
const int N=4e5+5;
typedef long long ll;
const ll base=1e9+7;
int root,root1,root2;
int tot,head[N],f[N],size[N],ans[N],next[N],go[N],del[N];
ll hash[N],tmp[N];
pair<ll,int>q1[N],q2[N];
int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}inline void add(int x,int y)
{go[++tot]=y;next[tot]=head[x];head[x]=tot;go[++tot]=x;next[tot]=head[y];head[y]=tot;
}
inline void getroot(int x,int fa)
{size[x]=1;for(int i=head[x];i;i=next[i]){int v=go[i];if (v==fa||del[i])continue;getroot(v,x);size[x]+=size[v];f[x]=max(f[x],size[v]);}f[x]=max(f[x],n-size[x]);if (!root||f[x]<f[root])root=x;
}
inline int gethash(int x,int fa)
{for(int i=head[x];i;i=next[i]){int v=go[i];if (v==fa||del[i])continue;gethash(v,x);}int cnt=0;for(int i=head[x];i;i=next[i]){int v=go[i];if (v!=fa&&!del[i])tmp[++cnt]=hash[v];}sort(tmp+1,tmp+cnt+1);hash[x]=base;fo(i,1,cnt)(((hash[x]*=base)^=tmp[i])+=tmp[i])^=tmp[i];
}
inline void solve1()
{fo(i,1,n-1){int x,y;x=read(),y=read();add(x,y);}root=0;int r1=0,r2=0;getroot(1,0);fo(i,1,n)if (f[i]==f[root])r2=r1,r1=i;if (r2){for(int i=2;i<=tot;i+=2){int v=go[i];if (go[i]==r1&&go[i^1]==r2||go[i]==r2&&go[i^1]==r1){del[i]=del[i^1]=1;break;}}add(n*2+1,r1);add(n*2+1,r2);root=n*2+1;}root1=root;gethash(root,0);
}
inline void solve2()
{fo(i,1,n-1){int x,y;x=read(),y=read();add(x+n,y+n);}root=0;int r1=0,r2=0;getroot(n+1,0);fo(i,n+1,n+n)if (f[i]==f[root])r2=r1,r1=i;if (r2){for(int i=2;i<=tot;i+=2){int v=go[i];if (go[i]==r1&&go[i^1]==r2||go[i]==r2&&go[i^1]==r1){del[i]=del[i^1]=1;break;} }add(n*2+2,r1);add(n*2+2,r2);root=n*2+2;}root2=root;gethash(root,0);
}
inline void getans(int x1,int x2,int fa1,int fa2)
{int tot1=0,tot2=0;for(int i=head[x1];i;i=next[i]){int v=go[i];if (v!=fa1&&!del[i])q1[++tot1]=mp(hash[v],v);}for(int i=head[x2];i;i=next[i]){int v=go[i];if (v!=fa2&&!del[i])q2[++tot2]=mp(hash[v],v);}sort(q1+1,q1+1+tot1);sort(q2+1,q2+1+tot2);fo(i,1,tot1)ans[q1[i].second]=q2[i].second;for(int i=head[x1];i;i=next[i]){int v=go[i];if (v!=fa1&&!del[i])getans(v,ans[v],x1,x2);}
}
int main()
{freopen("check.in","r",stdin);freopen("check.out","w",stdout);scanf("%d",&n);tot=1;solve1();solve2();if (hash[root1]!=hash[root2]){printf("NO\n");return 0;}ans[root1]=root2;getans(root1,root2,0,0);printf("YES\n");fo(i,1,n)printf("%d ",ans[i]-n);return 0;
}
JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查 树hash相关推荐
- Jzoj5454【NOIP2017提高A组冲刺11.5】仔细的检查
nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上.另一天nodgd更无聊,就又画了一张. 这时nodgd发现,两次画的顺序是不一样的,这就导致了原本的某一个节点u0在第一幅 ...
- JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查
题目 Sample Input 输入1: 3 1 2 2 3 1 3 3 2 输入2: 4 1 2 2 3 3 4 1 2 1 3 1 4 Sample Output 输出1: YES 1 3 2 输 ...
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
Description 给定一个1~n的排列x,每次你可以将x1~xi翻转.你需要求出将序列变为升序的最小操作次数.有多组数据. Input 第一行一个整数t表示数据组数. 每组数据第一行一个整数n, ...
- jzoj_5455. 【NOIP2017提高A组冲刺11.6】拆网线
Description 企鹅国的网吧们之间由网线互相连接,形成一棵树的结构.现在由于冬天到了,供暖部门缺少燃料,于是他们决定去拆一些网线来做燃料.但是现在有K只企鹅要上网和别人联机游戏,所以他们需要把 ...
- [JZOJ5459]【NOIP2017提高A组冲刺11.7】密室
Description 小X 正困在一个密室里,他希望尽快逃出密室. 密室中有N 个房间,初始时,小X 在1 号房间,而出口在N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会 ...
- JZOJ 5458. 【NOIP2017提高A组冲刺11.7】质数
Description 小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小X 认为,质数是一切自然数起源的地方. 在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数 ...
- JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线
Description 企鹅国的网吧们之间由网线互相连接,形成一棵树的结构.现在由于冬天到了,供暖部门缺少燃料,于是他们决定去拆一些网线来做燃料.但是现在有K只企鹅要上网和别人联机游戏,所以他们需要把 ...
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
Description 胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤. --太宰治<人间失格> 回顾我的一生,一共有n个事件,每一个事件有一个幸福值p_i. 我想用n-1条线把 ...
- JZOJ5445. 【NOIP2017提高A组冲刺11.2】失格
Description 胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤. --太宰治<人间失格> 回顾我的一生,一共有n个事件,每一个事件有一个幸福值p_i. 我想用n-1条线把 ...
最新文章
- 解题报告:P5960 【模板】差分约束算法(及常用技巧)
- 什么是RSS订阅 Really Simple Syndication(聚合)
- hibernate 一对多_java面试题之Hibernate
- 学习鸟哥的Linux私房菜笔记(2)——基础指令
- linux中gid和groups区别,linux用户与组管理
- Silverlight使用DataGrid的模板列(DataGridTemplateColumn)实现类似TreeListView控件的效果
- php在线编辑器fckeditor,[原创]继续给力:PHP中使用FckEditor在线编辑器详解
- CentOS下DB2数据库安装过程详解
- Unix/Linux Command Reference
- 16进制发送 mqtt客户端调试工具_MQTT客户端调试工具(MQTT Simulate Device)
- Android代码中实现关机
- linux 磁盘配额 期限,linux磁盘配额管理
- CentOS7安装PHP5.3.28
- Java基础面试题(史上最全基础面试题,精心整理100家互联网企业面经)
- gitbook踩坑指南-无法转pdf、epub等;pdf调字体大小
- 备战三个月,2021年阿里+腾讯+快手offer都已拿到!详解系列文章
- 机器学习复习:线性回归1
- 人脸识别登录:加强系统认证
- 6.824:FaRM笔记
- Java学习笔记----File类与IO流