树的同构

谁践踏了优雅 2021-11-04 10:26 420阅读 0赞

这里给出一种O(N)判断两棵树是否同构的方法:首先找出两个树的重心,然后对这个重心进行树的哈希。然后比对哈希结果,

没有找到例题,

但是有一个判断多棵树是否同构的例题,因为数据范围小,没有找重心,直接n2哈希的。

洛谷:树的同构

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const long long maxn=1001;
  4. long long ans[maxn][maxn],n,m,head[maxn],last[maxn],Next[maxn],tot,x;
  5. void add(int x,int y){ //建边
  6. last[++tot]=y;Next[tot]=head[x];head[x]=tot;
  7. }
  8. long long Hash(int x,int f) //树哈希
  9. {
  10. long long q[maxn],ans=maxn,top=0;
  11. for(int i=head[x];i;i=Next[i]) //遍历所以子节点
  12. if(last[i]!=f) //不能再次遍历以遍历的点,即x的父亲
  13. q[++top]=Hash(last[i],x);
  14. sort(q+1,q+top+1); //把哈希打得更乱
  15. for(int i=1;i<=top;i++) //对x点计算哈希值
  16. ans=ans*2333+q[i];
  17. return ans*2333+maxn+1;
  18. }
  19. int main(){
  20. cin>>m;
  21. for(int i=1;i<=m;i++)
  22. {
  23. tot=0;memset(head,0,sizeof(head)); //建边清0
  24. cin>>n;
  25. for(int j=1;j<=n;j++)
  26. {
  27. cin>>x;
  28. if(x!=0)add(x,j),add(j,x);
  29. }
  30. for(int j=1;j<=n;j++)
  31. ans[i][j]=Hash(j,0); //树哈希
  32. sort(ans[i]+1,ans[i]+n+1);
  33. for(int j=1,k=0;j<=i;j++)
  34. {
  35. while(k<=n) if(ans[i][++k]!=ans[j][k]) break; //找同构
  36. if(k>n){printf("%d\n",j);break;} //找到同构就输出
  37. }
  38. }
  39. return 0;
  40. }

发表评论

表情:
评论列表 (有 0 条评论,420人围观)

还没有评论,来说两句吧...

相关阅读

    相关 二叉判断

    一 题意理解 给定两颗树,T1,T2,若T1可以通过若干次的左右子互换变成T2,则称为这两棵树同构。 二 输入数据 先输入一个N,代表接下来的个数,然后輸入N组元素,

    相关

    7-1 树的同构 (30 point(s)) 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,

    相关

    这里给出一种O(N)判断两棵树是否同构的方法:首先找出两个树的重心,然后对这个重心进行树的哈希。然后比对哈希结果, 没有找到例题, 但是有一个判断多棵树是否同构的例题,因为