• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
XD-TEST
博客园    首页    新随笔    联系   管理    订阅  订阅

BZOJ4337 BJOI2015 树的同构

  构造一个靠谱点的树哈希函数,每个树以每个点都为根算一次哈希值,然后归类一下有相同哈希值的树就行了。

  代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define nc() getchar()
 4 #define N 500100
 5 int dp,pre[N],p[N],ans[N],tt[N],n,i,m[N],a,j,k;
 6 long long q,hash[N],s[N],v[N];
 7 void link(int x,int y)
 8 {
 9     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
10 }
11 void root(int x,int fa)
12 {
13     int i=p[x];
14     long long ans=1;
15     s[x]=1;
16     while (i)
17     {
18         if (tt[i]!=fa)
19         {
20             root(tt[i],x);
21             long long tmp=v[tt[i]]+131;
22             s[x]=s[x]+s[tt[i]];
23             v[x]=v[x]+tmp;
24         }
25         i=pre[i];
26     }
27     v[x]=v[x]*s[x]%1000000007;
28 }
29 int main()
30 {
31     scanf("%d",&n);
32     for (i=1;i<=n;i++)
33     {
34         scanf("%d",&m[i]);
35         dp=0;
36         for (j=1;j<=m[i];j++) p[j]=0;
37         for (j=1;j<=m[i];j++)
38         {
39             scanf("%d",&a);
40             if (a)
41             {
42                 link(a,j);
43                 link(j,a);
44             }
45         }
46         
47         for (j=1;j<=m[i];j++)
48         {
49             for (k=1;k<=m[i];k++)
50             s[k]=0,v[k]=0;
51             root(j,0);q=v[j];
52             for (k=1;k<i;k++)
53             if ((m[k]==m[i])&&(hash[k]==q)) 
54             {
55                 ans[i]=k;break;
56             }
57         }
58         if (ans[i]==0) ans[i]=i,hash[i]=q;
59         
60     }
61     for (i=1;i<=n;i++)
62     printf("%d\n",ans[i]);
63 }

 

posted @ 2016-04-13 19:59  fzmh  阅读(371)  评论(0)    收藏  举报
刷新页面返回顶部
Copyright © 2025 fzmh
Powered by .NET 9.0 on Kubernetes