zoukankan      html  css  js  c++  java
  • 洛谷 P5043 树的同构 题解

    题面

    本题的难度其实不及紫题的难度。主要是在hash时的处理细节比较繁琐;

    首先是树hash的模板:

    long long treehash(int u,int fa)
    {
        long long q[1001];
        long long num=0;
        long long ans=1;
        for(int i=head[u];i;i=star[i].nxt){
            int v=star[i].to;
            if(v==fa) continue;
            q[++num]=treehash(v,u);
        }
        sort(q+1,q+num+1);
        for(int i=1;i<=num;i++){
            ans=ans*2333+q[i];
        }
        return ans*2333+1;
    }

    对于无根树在数据不多的时候可以依次枚举每个点当根时的根节点的hash值,然后将这些树上hash值变为一组数的hash值;

    然后n^2比较每棵树的线性hash值就可以了;

    #include <bits/stdc++.h>
    using namespace std;
    struct littlestar{
        int to;
        int nxt;
    }star[20010];
    long long head[20010],cnt;
    void add(int u,int v)
    {
        star[++cnt].to=v;
        star[cnt].nxt=head[u];
        head[u]=cnt;
    }
    long long myhash[20010];
    long long treehash(int u,int fa)
    {
        long long q[1001];
        long long num=0;
        long long ans=1;
        for(int i=head[u];i;i=star[i].nxt){
            int v=star[i].to;
            if(v==fa) continue;
            q[++num]=treehash(v,u);
        }
        sort(q+1,q+num+1);
        for(int i=1;i<=num;i++){
            ans=ans*2333+q[i];
        }
        return ans*2333+1;
    }
    long long lala[20010];
    long long ans[20010];
    int main ()
    {
        int t;
        cin>>t;
        for(int i=1;i<=t;i++){
            memset(head,0,sizeof(head));
            memset(lala,0,sizeof(lala));
            cnt=0;
            int n;
            cin>>n;
            int root=1;
            for(int j=1;j<=n;j++){
                int x;
                scanf("%d",&x);
                if(x==0){
                    root=j;
                    continue;
                } 
                add(x,j);
                add(j,x);        
            }
            for(int j=1;j<=n;j++) myhash[j]=treehash(j,0);
            sort(myhash+1,myhash+1+n);
            for(int j=1;j<=n;j++) lala[j]=lala[j-1]*myhash[j]+233;
            ans[i]=lala[n];
            for(int j=1;j<=i;j++){
                if(ans[i]==ans[j]){
                    cout<<j<<endl;
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    vue axios的使用
    html5 css写出一个实心三角形和空心三角行
    弹出新页面并使整个旧页面背景变暗功能的实现代码
    radio 单选按钮 选中多个
    搭建脚手架cli2.x环境
    页面滚动条位置触发事件
    DataGridView行号发生变化 使用的事件
    eclipse git 忽略文件
    eclipse git 分享项目到GitHub上
    eclipse git 创建新分支 合并分支 删除分支
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11314822.html
Copyright © 2011-2022 走看看