zoukankan      html  css  js  c++  java
  • 【bzoj4337】【Bjoi2015】树的同构

    • 题解

      • 无标号树的HASH:
      • 找到树的重心,以重心为根求出括号序列;
      • 由于树的重心最多只有两个,取字典序的最小括号序列HASH即可
      • 树的括号序列$s_{u}="(s_{v_{1}},s_{v_{2}},s_{v_{3}},...,s_{v_{n}})"$,同时字典序$s_{v_{1}} <= s_{v_{2}} <= ,... $ 
      • 有标号树的HASH:
      • 个人认为可以直接$prufer$序列$HASH$
      • 或者直接将儿子排个序$hash$,(总之乱搞
      •  1 #include<bits/stdc++.h>
         2 #define ll long long
         3 #define mod 998244353
         4 using namespace std;
         5 const int N=51;
         6 int n,m,hd[N],o,sz[N],mx[N],Mx,tot;
         7 struct Edge{int v,nt;}E[N<<1];
         8 map<int,int>h;
         9 string now,s[N],tmp[N];
        10 void adde(int u,int v){
        11     E[o]=(Edge){v,hd[u]};hd[u]=o++;
        12     E[o]=(Edge){u,hd[v]};hd[v]=o++;
        13 }
        14 void get_rt(int u,int fa){
        15     sz[u]=1;mx[u]=0;
        16     for(int i=hd[u];~i;i=E[i].nt){
        17         int v=E[i].v;
        18         if(v==fa)continue;
        19         get_rt(v,u);
        20         sz[u]+=sz[v];
        21         mx[u]=max(mx[u],sz[v]);
        22     }
        23     mx[u]=max(m-sz[u],mx[u]);
        24     if(mx[u]<Mx)Mx=mx[u];
        25 }
        26 void dfs(int u,int fa){
        27     s[u]="(";
        28     for(int i=hd[u];~i;i=E[i].nt){
        29         int v=E[i].v;
        30         if(v==fa)continue;
        31         dfs(v,u);
        32     }
        33     tot=0;
        34     for(int i=hd[u];~i;i=E[i].nt){
        35         int v=E[i].v;
        36         if(v==fa)continue;
        37         tmp[++tot]=s[v];
        38     }
        39     sort(tmp+1,tmp+tot+1);
        40     for(int i=1;i<=tot;i++)s[u]=s[u]+tmp[i];
        41     s[u]+=")";
        42 }
        43 int main(){
        44     #ifndef ONLINE_JUDGE
        45     freopen("bzoj4337.in","r",stdin);
        46     freopen("bzoj4337.out","w",stdout);
        47     #endif
        48     scanf("%d",&n);
        49     for(int I=1;I<=n;I++){
        50         o=1;memset(hd,-1,sizeof(hd));
        51         scanf("%d",&m);
        52         for(int i=1,x;i<=m;i++){
        53             scanf("%d",&x);
        54             if(x)adde(x,i);
        55         }
        56         Mx=m;get_rt(1,0);
        57         now="";
        58         for(int i=1;i<=m;i++)if(Mx==mx[i]){
        59             dfs(i,0);
        60             if(now<s[i])now=s[i];
        61         }
        62         ll x=0;
        63         for(int i=0;i<(int)now.length();i++){
        64             x = ((x<<1) + now[i])%mod;
        65         }
        66         //printf("%s
        ",now.c_str());
        67         if(!h[x])h[x]=I;
        68         printf("%d
        ",h[x]);
        69     }
        70     return 0;
        71 }
        bzoj4337

  • 相关阅读:
    iOS ARC编译器规则和内存管理规则
    Servlet与JSP的关系
    传统javabean与spring中的bean的区别
    servlet学习笔记
    JAVA里面"=="和euqals的区别
    java垃圾回收
    java中初始化块、静态初始化块和构造方法
    抽象类与接口的区别
    Servlet 与 CGI 的比较
    spring的事务传播特性
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10241662.html
Copyright © 2011-2022 走看看