• 洛谷 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;
    }
  • 相关阅读:
    HDU_1285_拓扑排序(优先队列)
    HDU_1087_Super Jumping! Jumping! Jumping!_dp
    STL_优先队列_(转载)
    数据结构课程笔记_拓扑排序
    滋阴清火中药方 (推荐--自用)
    文件与文档内容搜索工具软件
    CrossUI SPA Builder ---- feathers API框架
    广州交警网上车管所
    BIM 相关资料
    WIN10 ISO 官方
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11314822.html
Copyright © 2020-2023  润新知