日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[BJOI2015] 树的同构

發布時間:2025/7/25 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BJOI2015] 树的同构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

4337: BJOI2015 樹的同構

Time Limit: 10 Sec??Memory Limit: 256 MB
Submit: 1092??Solved: 460
[Submit][Status][Discuss]

Description

樹是一種很常見的數據結構。 我們把N個點,N-1條邊的連通無向圖稱為樹。 若將某個點作為根,從根開始遍歷,則其它的點都有一個前驅,這個樹就成為有根樹。 對于兩個樹T1和T2,如果能夠把樹T1的所有點重新標號,使得樹T1和樹T2完全相 同,那么這兩個樹是同構的。也就是說,它們具有相同的形態。 現在,給你M個有根樹,請你把它們按同構關系分成若干個等價類。

Input

第一行,一個整數M。 接下來M行,每行包含若干個整數,表示一個樹。第一個整數N表示點數。接下來N 個整數,依次表示編號為1到N的每個點的父親結點的編號。根節點父親結點編號為0。

Output

輸出M行,每行一個整數,表示與每個樹同構的樹的最小編號。

Sample Input

4
4 0 1 1 2
4 2 0 2 3
4 0 1 1 1
4 0 1 2 3

Sample Output

1
1
3
1

HINT

【樣例解釋】?

?

編號為1, 2, 4 的樹是同構的。編號為3 的樹只與它自身同構。?

?

100% 的數據中,1 ≤ N, M ≤ 50。 ??? 樹hash第一題。 ??? 可以先隨機一個序列val,表示每一位對應的權值,然后樹上hash的計算方式是 f[x] = ∑ g[son][i] * val[i]? ,其中 g[son][i] 表示 x兒子中f[]第i大的值。。。。 ??? 然后直接做就行了,把有根樹轉化成無根樹,以每個點為根的hash值排序之后必須全相同才同構。。。。 ??? 這么做的話結構相同的樹是肯定會被判成一樣的,結構不同的樹有極小的概率會被判成一樣的。。。 #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=55,B=9991; int m,to[maxn*2],ne[maxn*2],hd[maxn],num,now,n[maxn]; ll f[maxn],val[maxn],H[maxn][maxn];inline void add(int x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;}inline void init(){memset(hd,0,sizeof(hd)),num=0; }void dfs(int x,int fa){f[x]=0;if(!ne[hd[x]]&&to[hd[x]]==fa){ f[x]=1; return;}int N=0;ll b[maxn];for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){dfs(to[i],x),b[++N]=f[to[i]];}sort(b+1,b+N+1);for(int i=1;i<=N;i++) f[x]+=b[i]*val[i]; }int main(){srand(time(0));for(int i=1;i<=50;i++) val[i]=rand()*233473ll+rand()*19260817ll+rand();scanf("%d",&m);for(now=1;now<=m;init(),now++){scanf("%d",n+now);for(int i=1,fa;i<=n[now];i++){scanf("%d",&fa);if(fa) add(fa,i),add(i,fa);}for(int i=1;i<=n[now];i++) dfs(i,0),H[now][i]=f[i];}for(int i=1;i<=m;i++) sort(H[i]+1,H[i]+n[i]+1);for(int i=1;i<=m;i++)for(int j=1;j<=i;j++) if(n[i]==n[j]){bool flag=1;for(int k=1;k<=n[i];k++) if(H[i][k]!=H[j][k]){flag=0;break;}if(flag){printf("%d\n",j);break;}}return 0; }

?

轉載于:https://www.cnblogs.com/JYYHH/p/9112145.html

總結

以上是生活随笔為你收集整理的[BJOI2015] 树的同构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。