P5043 【模板】树同构([BJOI2015]树的同构 // P4323 [JSOI2016]独特的树叶

P5043 【模板】树同构([BJOI2015]树的同构 // P4323 [JSOI2016]独特的树叶一、P5043【模板】树同构([BJOI2015]树的同构):#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<cmath>#include<que

一、P5043 【模板】树同构([BJOI2015]树的同构):
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=55;
int head[maxn],ver[maxn<<1],nt[maxn<<1];
int n[maxn],si[maxn],tot=1;
unsigned ll ha[maxn][maxn],f[maxn];
int p[]={ 
   0,2,3,5,7,11,13,17,19,23,29,31,37,
         41,43,47,53,59,61,67,71,73,79,83,89,97,
         101,103,107,109,113,127,131,137,139,149,
         151,157,163,167,173,179,181,191,193,197,
         199,211,223,227,229};

void init(void)
{ 
   
    memset(head,0,sizeof(head));
    tot=1;
}

void add(int x,int y)
{ 
   
    ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
}

void dfs(int x,int fa)
{ 
   
    f[x]=si[x]=1;
    for(int i=head[x];i;i=nt[i])
    { 
   
        int y=ver[i];
        if(y==fa) continue;
        dfs(y,x);
        f[x]+=f[y]*p[si[y]];
        si[x]+=si[y];
    }
}

bool check(int i,int j)
{ 
   
    for(int k=1;k<=n[i];k++)
    { 
   
        if(ha[i][k]!=ha[j][k]) return false;
    }
    return true;
}

int main(void)
{ 
   
    int m,fa;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    { 
   
        init();
        scanf("%d",&n[i]);
        for(int j=1;j<=n[i];j++)
        { 
   
            scanf("%d",&fa);
            if(fa) add(fa,j),add(j,fa);
        }
        for(int j=1;j<=n[i];j++)
        { 
   
            dfs(j,0);
            ha[i][j]=f[j];
        }
        sort(ha[i]+1,ha[i]+n[i]+1);
    }
    for(int i=1;i<=m;i++)
    { 
   
        bool flag=true;
        for(int j=1;j<=i;j++)
        { 
   
            if(n[i]==n[j]&&check(i,j))
            { 
   
                printf("%d\n",j);
                flag=false;
                break;
            }
        }
        if(flag)
            printf("%d\n",i);
    }
    return 0;
}


二、P4323 [JSOI2016]独特的树叶:
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define llu unsigned ll
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=1000100;
int head[maxn],ver[maxn],nt[maxn],d[maxn];
int fa[maxn],si[maxn],tot=1,n;
llu g[maxn],f[maxn];
int p[maxn<<1],cnt=0;
bool ha[maxn<<1];
set<llu> se;

void prime(void)
{ 
   
    ha[1]=true;
    for(int i=2;i<(maxn<<1);i++)
    { 
   
        if(!ha[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<(maxn<<1);j++)
        { 
   
            ha[i*p[j]]=true;
            if(i%p[j]==0) break;
        }
    }
}

void init(void)
{ 
   
    memset(head,0,sizeof(head));
    tot=1;
    n++;
}

void add(int x,int y)
{ 
   
    ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
}

void dfs1(int x,int ff)
{ 
   
    f[x]=si[x]=1;
    for(int i=head[x];i;i=nt[i])
    { 
   
        int y=ver[i];
        if(y==ff) continue;
        dfs1(y,x);
        f[x]+=f[y]*p[si[y]];
        si[x]+=si[y];
    }
}

void dfs2(int x,int ff)
{ 
   
    for(int i=head[x];i;i=nt[i])
    { 
   
        int y=ver[i];
        if(y==ff) continue;
        g[y]=f[y]+(g[x]-f[y]*p[si[y]])*p[n-si[y]];
        dfs2(y,x);
    }
}


int main(void)
{ 
   
    prime();
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<n;i++)
    { 
   
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs1(1,0);
    g[1]=f[1];
    dfs2(1,0);
    for(int i=1;i<=n;i++)
        se.insert(g[i]);

    init();
    for(int i=1;i<n;i++)
    { 
   
        scanf("%d%d",&x,&y);
        d[x]++,d[y]++;
        add(x,y);
        add(y,x);
        fa[x]=y,fa[y]=x;//注意这里叶子节点怎么找它的上一节点
    }
    dfs1(1,0);
    g[1]=f[1];
    dfs2(1,0);

    for(int i=1;i<=n;i++)
    { 
   
        if(d[i]==1&&se.find(g[fa[i]]-p[1])!=se.end())
        { 
   
            printf("%d\n",i);
            break;
        }
    }

    return 0;
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/35602.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注