这题就是无脑,萌新不知道什么叫树的重心,也不知道什么叫最小表示法排序,萌新只会无脑hash
对每一棵树,每一个节点为根跑一次hash值,强行判断就好
最后用并查集维护一下,其他看代码吧
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
const int mod = 1e9+7;
const int jinzhi = 251;
const int maxn = 101;
const int mk = 101;
const int P = 19260817;
typedef long long ll;
struct node
{
int to,next;
}edge[mk][maxn*2];
int cnt[mk],head[mk][maxn],n,m,val[maxn],tot,f[maxn];
long long size[mk][maxn][maxn],dep[mk][maxn][maxn],hbsh[mk][maxn][maxn];
struct _Hash
{
ll hbsh[maxn];
int pos;
}Hash[maxn];
priority_queue< int > q[maxn];
void add(int from,int to,int k)
{
edge[k][++cnt[k]].to=to;
edge[k][cnt[k]].next=head[k][from];
head[k][from]=cnt[k];
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int merge(int a,int b)
{
int f1=find(a),f2=find(b);
if(f1!=f2)
f[max(f1,f2)]=min(f1,f2);
}
void dfs(int u,int fa,int k,int root)
{
size[k][root][u]=1;dep[k][root][u]=dep[k][root][fa]+1;
for(int i=head[k][u];i;i=edge[k][i].next)
{
int to=edge[k][i].to;
if(to==fa)continue;
dfs(to,u,k,root);
size[k][root][u]+=size[k][root][to];
}
hbsh[k][root][u]=(ll)size[k][root][u]*(ll)P%mod*(ll)dep[k][root][u]%mod;
}
bool cmp1(int a,int b){return a<b;}
bool check(ll a[],ll b[],int Size1,int Size2)
{
if(Size1!=Size2)return false;
for(int i=1;i<=Size1;i++)
{
if(a[i]!=b[i])return false;
}
return true;
}
int main()
{
scanf("%d",&m);
for(int i=1;i<=m;i++)f[i]=i;
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&val[i]);
for(int j=1;j<=val[i];j++)
{
scanf("%d",&x);
if(x==0)continue;
else add(j,x,i),add(x,j,i);
}
}
for(int i=1;i<=m;i++)
for(int j=1;j<=val[i];j++)
dfs(j,0,i,j),sort(hbsh[i][j],hbsh[i][j]+val[i]+2,cmp1);
for(int i=1;i<=m;i++)
for(int j=1;j<=val[i];j++)
for(int k=1;k<=val[i];k++)
Hash[i].hbsh[j]=(Hash[i].hbsh[j]*jinzhi+hbsh[i][j][k])%mod,Hash[i].pos=i;
for(int i=1;i<=m;i++)for(int j=1;j<=val[i];j++)sort(Hash[i].hbsh+1,Hash[i].hbsh+1+val[i],cmp1);
for(int i=1;i<=m;i++)
{
for(int j=1;j<i;j++)
{
if(check(Hash[i].hbsh,Hash[j].hbsh,val[Hash[i].pos],val[Hash[j].pos]))
merge(Hash[i].pos,Hash[j].pos);
}
}
for(int i=1;i<=m;i++)
cout<<find(i)<<endl;
}