zoukankan      html  css  js  c++  java
  • BZOJ4337 : BJOI2015 树的同构

    对于一棵无根树,它的重心个数不超过2。

    枚举每个重心,以重心为根求出这棵有根树的最小表示,然后取字典序最大的即可。

    对于有根树的最小表示,可以看成括号序列,每次把子树的括号序列按字典序排序后依次串连起来即可。

    #include<cstdio>
    #include<string>
    #include<algorithm>
    #define N 55
    using namespace std;
    int T,n,i,j,k,x,g[N],v[N<<1],nxt[N<<1],ed,f[N],son[N],mx;string h[N],q[N],val[N];
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    void findroot(int x,int y){
      son[x]=1;f[x]=0;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y){
        findroot(v[i],x);
        son[x]+=son[v[i]];
        if(son[v[i]]>f[x])f[x]=son[v[i]];
      }
      if(n-son[x]>f[x])f[x]=n-son[x];
      if(f[x]<mx)mx=f[x];
    }
    void dfs(int x,int y){
      h[x]="(";
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x);
      int t=0;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y)q[t++]=h[v[i]];
      if(t>1)std::sort(q,q+t);
      for(int i=0;i<t;i++)h[x]+=q[i];
      h[x]+=")";
    }
    string solve(){
      int i;string t="";
      scanf("%d",&n);
      for(ed=0,mx=n,i=1;i<=n;i++)g[i]=0;
      for(i=1;i<=n;i++){
        scanf("%d",&x);
        if(x)add(i,x),add(x,i);
      }
      findroot(1,0);
      for(i=1;i<=n;i++)if(f[i]==mx){
        dfs(i,0);
        if(h[i]>t)t=h[i];
      }
      return t;
    }
    int main(){
      scanf("%d",&T);
      for(i=1;i<=T;i++)val[i]=solve();
      for(i=1;i<=T;printf("%d
    ",k),i++)for(j=k=i;j;j--)if(val[j]==val[i])k=j;
      return 0;
    }
    

      

  • 相关阅读:
    Java基础回顾---JVM&JDK&JRE
    学习
    学习
    学习
    进度
    进度
    毕设进度
    学习进度
    Beta阶段项目总结
    第二阶段冲刺——seven
  • 原文地址:https://www.cnblogs.com/clrs97/p/4982839.html
Copyright © 2011-2022 走看看