• 【树hs】[BJOI2015]树的同构


    题目描述
    树是一种很常见的数据结构。 我们把N个点,N-1条边的连通无向图称为树。 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树。 对于两个树T1和T2,如果能够把树T1的所有点重新标号,使得树T1和树T2完全相 同,那么这两个树是同构的。也就是说,它们具有相同的形态。 现在,给你M个有根树,请你把它们按同构关系分成若干个等价类。
    
    输入格式
    第一行,一个整数M。 接下来M行,每行包含若干个整数,表示一个树。第一个整数N表示点数。接下来N 个整数,依次表示编号为1到N的每个点的父亲结点的编号。根节点父亲结点编号为0。
    
    输出格式
    输出M行,每行一个整数,表示与每个树同构的树的最小编号。
    
    样例一
    input
    
    4 
    4 0 1 1 2 
    4 2 0 2 3 
    4 0 1 1 1 
    4 0 1 2 3 
    output
    
    1 
    1 
    3 
    1 
    样例解释
    编号为1, 2, 4 的树是同构的。编号为3 的树只与它自身同构。
    
    限制与约定
    对于100%的数据,1≤N,M≤501≤N,M≤50
    时间限制:1s1s
    空间限制:256MB
    T

    这道题是树hs裸题,树hs的思路就是,先把每个节点的点权赋为1,然后父节点累加子节点平方和自己的值向上返回,

    就是一个递归的过程,然后自然溢出

    但是每个树的根节点可能会不同,所以我们要有对于每个树选根的唯一标准

    对,就是树重心,一个树可能有多个重心,那么我们只需要一个超级原点就ok 了

    最后比较超级原点的hs值,就能知道是否同构

    有一点玄学的地方,就是用seed的方式过不了,也不知道是为什么

     1 #include<bits/stdc++.h>
     2 #define N 100
     3 #define clear(a,val) memset(a,val,sizeof(a))
     4 using namespace std;
     5 typedef unsigned long long ult;
     6 int n,m,f,cnt=1,pp;
     7 int head[N],nxt[N*2],to[N*2],size[N],ans[N];
     8 ult vv[N],val[N];
     9 inline void add(int u,int v)
    10     {nxt[cnt]=head[u],to[cnt]=v,head[u]=cnt++;}
    11 inline void cl(){
    12     clear(size,0),clear(ans,0),clear(head,-1),cnt=1,pp=0;
    13 }
    14 int dfs(int now,int fa)
    15 {
    16     size[now]=1;int ma=-1;
    17     for(int i=head[now];i!=-1;i=nxt[i])
    18     {
    19         int t=to[i];
    20         if(t==fa)continue;
    21         size[now]+=dfs(t,now);
    22         ma=max(ma,size[t]);
    23     }
    24     ma=max(ma,n-size[now]);
    25     if(ma<=(n>>1))ans[++pp]=now;
    26     return size[now];
    27 }
    28 inline void weigh()
    29 {
    30     dfs(1,-1);
    31     for(int i=1;i<=pp;i++)
    32         add(n+1,ans[i]);
    33 }
    34 ult cal(int now,int fa)
    35 {
    36     vv[now]=1;
    37     for(int i=head[now];i!=-1;i=nxt[i])
    38     {
    39         int t=to[i];
    40         if(t==fa)continue;
    41         vv[now]+=cal(t,now);
    42     }
    43     return vv[now]*vv[now];
    44 }
    45 inline void init_build_weigh_solve()
    46 {
    47     clear(head,-1);
    48     scanf("%d",&m);
    49     for(int i=1;i<=m;i++)
    50     {
    51         cl();
    52         scanf("%d",&n);
    53         for(int j=1;j<=n;j++)
    54         {
    55             scanf("%d",&f);
    56             if(f==0)continue;
    57             else add(f,j),add(j,f);
    58         }
    59         weigh();
    60         val[i]=cal(n+1,-1);
    61     }
    62     for(int i=1;i<=m;i++)
    63     {
    64         for(int j=1;j<=i;j++)
    65         {
    66             if(val[i]==val[j])
    67             {
    68                 printf("%d
    ",j);
    69                 break;
    70             }
    71         }
    72     }
    73 }
    74 int main()
    75 {
    76     init_build_weigh_solve();
    77     return 0;
    78 }
  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10204381.html
Copyright © 2020-2023  润新知