切了省选题+紫题,来写个题解

这题其实挺水,才120行代码

该题写了我一天(上午1.5h,晚上10min = 一天)

hash,对于节点A,$$hashval[A] = {hashval[i]\times2333^{num} | i \in son[A] }$$ , 并且hashval[i]大于任何在他前面加的数,num为目前加到第几个

写成代码就是

function Hash(int n){
vector V ;
for_each(i in son[n]) do
HV[i] = Hash(i) ;
V.pushback(HV[i]) ;
V.sort()
for_each(i in V)
HV[n] = HV[n]*2333+HV[i] ;
return HV[n]*2333+1002 ;
//HV[i]初值为1
}

那么对于树中的每个节点做一遍Hash,时间复杂度为$$O(N \times (N+NlogN+N))$$

所以总的的时间复杂度为$$O(M \times N \times NlogN) == O(N^3logN)$$

说人话:$$O(\text{能过})$$

\[\]

\[\]

Talk is free , show me the code

#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std ;
inline void read(int &x) {
char ch=getchar();
int s=0,f=1;
while (!(ch>='0'&&ch<='9')) {
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9') {
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
x=s*f;
}
class TREE{
private:
vector<int> son[55] ;
int hashval[55] ;
int H[55] ;
bool inq[55] ;
int size[55] ;
int root ;
int n ;
int check(vector<int> N){
int S = N.size() ;
for(int j:N) {
if(inq[j]) --S ;
}
return S ;
}
public:
//这个MIAOMIAOMIAO函数就是Hash啦喵~
int MIAOMIAOMIAO(int n,int f){
inq[n] = true ;
vector<int> V ;
for(const int & i : son[n]){
if(i==f) continue ;
//cout<<"dfs in dot "<<i<<endl ;
hashval[i] = MIAOMIAOMIAO(i,n) ;
//cout<<"HashVal["<<i<<"] = "<<hashval[i]<<endl ;
V.push_back(hashval[i]) ;
//cout<<"HashVal["<<n<<"] = "<<hashval[n]<<endl ;
}
sort(V.begin(),V.end()) ;
for(const int& i : V)
hashval[n] = hashval[n]*2333 + i ;
//hashval[n] = 2333*hashval[n] + 1001 ;
return hashval[n]*2333+1002 ;
}
void getsize(int n,int f){
inq[n] = true ;
if(!check(son[n])) size[n] = 1 ;
for(int i:son[n]){
if(i!=f) getsize(i,n) ;
size[n] += size[i] ;
}
}
bool comp(const int& a,const int& b){
return a>b ;
}
int sZ() {return this->n ;}
void init(){
read(n) ;
for(int i=1;i<=n;++i){
int x ;
read(x) ;
if(x==0) { root=i ; continue ; }
son[x].push_back(i) , son[i].push_back(x) ;
}
//cout<<"Root = "<<root<<endl ;
getsize(root,root) ;
memset(inq,0,sizeof(inq)) ;
for(int i=1;i<=n;++i){
sort(son[i].begin() , son[i].end() , [this](int a, int b) -> bool { return size[a] < size[b]; }) ;
}
for(int j=1;j<=n;++j) hashval[j] = 1 ;
for(int i=1;i<=n;++i){
MIAOMIAOMIAO(i,i) ;
H[i] = hashval[i] ;
memset(inq,0,sizeof(inq)) ;
for(int j=1;j<=n;++j) hashval[j] = 1 ;
}
//for(int i=1;i<=n;++i) cout<<H[i]<<" ";
//cout<<endl ;
}
int gethashval(int DI){
return H[DI] ;
}
} ;
TREE Index[55] ;
int m ;
int HVL[55] ;
int ans[55][55] ;
int main(){
read(m) ;
for(int i=1;i<=m;++i){
//cout<<"TREE "<<i<<endl ;
Index[i].init() ;
HVL[i] = i ;
int n = Index[i].sZ() ;
for(int j=1;j<=n;++j){
ans[i][j] = Index[i].gethashval(j) ;
}
sort(ans[i]+1,ans[i]+n+1) ;
for(int j=1;j<=i;++j){
int k = 0 ;
while(k<=n)
if(ans[i][++k]!=ans[j][k])
break ;
if(k>n) { HVL[i] = j ; break ; }
}
}
for(int i=1;i<=m;++i) {
printf("%d\n",HVL[i]) ;
}
}

Oh对了

本代码使用C++11标准并对每棵树封装

提交时注意~~(我不会告诉你我因为这个WA了一次喵~

还有说下那个for

for(const int& i : vector1) -> 对于每个vector1中的元素i,按vector1中的存放顺序访问

所以这个写起来省力~~(我不会告诉你还可以写for(auto& i:vector1)但是我忘了写喵~

题解【[BJOI2015]树的同构】的更多相关文章

  1. BZOJ 4337: BJOI2015 树的同构 树hash

    4337: BJOI2015 树的同构 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4337 Description 树是一种很常见的数 ...

  2. bzoj4337: BJOI2015 树的同构 树哈希判同构

    题目链接 bzoj4337: BJOI2015 树的同构 题解 树哈希的一种方法 对于每各节点的哈希值为hash[x] = hash[sonk[x]] * p[k]; p为素数表 代码 #includ ...

  3. 【BZOJ4337】BJOI2015 树的同构 括号序列

    [BZOJ4337]BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱 ...

  4. 4337: BJOI2015 树的同构

    题解: 树的同构的判定 有根树从根开始进行树hash 先把儿子的f进行排序 $f[i]=\sum_{j=1}^{k} { f[j]*prime[j]} +num[i]$(我没有仔细想这样是不是树是唯一 ...

  5. [BZOJ4337][BJOI2015]树的同构(树的最小表示法)

    4337: BJOI2015 树的同构 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1023  Solved: 436[Submit][Status ...

  6. BZOJ4337:[BJOI2015]树的同构——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4337 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根, ...

  7. [BJOI2015]树的同构

    嘟嘟嘟 判断树的同构的方法就是树上哈希. 如果树是一棵有根树,那么只要从根节点出发dfs,每一个节点的哈希值等于按传统方式算出来的子树的哈希值的结果.需要注意的是,算完子树的哈希值后要先排序再加起来, ...

  8. BZOJ4337:[BJOI2015]树的同构(树hash)

    Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如 ...

  9. 题解 P5043 【【模板】树同构([BJOI2015]树的同构)】

    进入正题 题意:将所有树结构相同的树归类. 思路 嗯,这道题让我们把树的结构归类,自然而然就想到了哈希,我们对这整颗树哈希一遍.然后判同构就十分之简单了.只需要找哈希值一样的树就可以了. 其实真得很简 ...

随机推荐

  1. Apache NiFi Processor实战

    1 前言 Apache NiFi是什么?NiFi官网给出如下解释:“一个易用.强大.可靠的数据处理与分发系统”.通俗的来说,即Apache NiFi 是一个易于使用.功能强大而且可靠的数据处理和分发系 ...

  2. Java 第一次课堂测试总结。

    Java 第一次课堂测试总结. 昨天参加了JAVA的开学测试,课上没有完成计算基点的功能,以下是修改完成后的代码.  首先是ScoreInformation类来存储学生信息. //信1805-1 王正 ...

  3. 初识MyBatis-Generator

    详细请见: http://www.mybatis.org/generator/quickstart.html 使用mybatis-generator-core-x.x.x.jar加上配置文件来生成 1 ...

  4. 2020/2/2 PHP代码审计之反序列化

    0x00 序列化与反序列化 序列化: serialize()把对象转换为字节序列的过程称为对象的序列化 反序列化: unserialize()把字节序列恢复为对象的过程称为对象的反序列化 0x01 序 ...

  5. Django项目同步到码云

    本篇博客主要记录下将刚刚初始化后的Django项目部署到码云中,首先我们需要到码云中注册一个账号,下面会讲解下如何在码云中建立一个仓库,再将其克隆到本地.最后将本地的项目推送到码云的仓库中. 码云内初 ...

  6. group_concat用法以及字符串太长显示不全

    由于group_concat默认的长度是1024,所以要将最大长度修改 首先执行 SET SESSION group_concat_max_len = 10240;#一次查询有效 然后再进行拼接 se ...

  7. 在linux上部署多个tomcat

    1.vim  /etc/profile ##########first tomcat########### CATALINA_BASE=/usr/apache-tomcat--fore CATALIN ...

  8. dd if= of= MBR

    1.备份分区表信息 sudo fdisk -l >hda.txt  #分区表信息重定向输出到文件中 2.备份MBR sudo dd if=/dev/sda of=mbr bs=512 count ...

  9. 十五、Numpy-科学计算基础库

    Numpy:          NumPy(Numerical Python) 是科学计算基础库,提供大量科学计算相关功能,比如数据统计,随机数生成等.其提供最核心类型为多维数组类型(ndarray) ...

  10. 如何写出高质量的Python代码--做好优化--改进算法点滴做起

    小伙伴你的程序还是停留在糊墙吗?优化代码可以显示程序员的素质欧! 普及一下基础了欧: 一层for简写:y = [1,2,3,4,5,6],[(i*2) for i in y ]       会输出  ...