刷題總結——樹的同構(bzoj4337 樹上hash)
阿新 • • 發佈:2017-10-07
inline rime sin com amp const 註意 turn input
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解決樹的同構問題的模板題···
先說如何進行樹上hash,設f[i]為以i為節點的hash值,則
f[i]=sigma(f[j]*prime[j]) j為son[i]
其中prime為預處理出來的素數表···註意f[j]需要進行排序····
然後對於兩顆待判定的樹,將兩顆樹分別以樹上每一個節點為根節點求hash值··將根節點的hash值儲存起來排序然後兩顆樹一一比對··如果完全一樣則兩棵樹就一樣
代碼:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=55; int hash[N][N],n,que[N]; int tot,fst[N],nxt[N*2],go[N*2],f[N]; int prime[]={0,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,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317}; inline void comb(int a,int b) { nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b; nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a; } inline void dfs(int u,int fa) { unsigned int st[N];int tot=0; st[++tot]=1; for(int e=fst[u];e;e=nxt[e]) { int v=go[e];if(v==fa) continue; dfs(v,u); st[++tot]=f[v]; } f[u]=0;sort(st+1,st+tot+1); for(int i=1;i<=tot;i++) f[u]+=st[i]*prime[i]; } int main() { // freopen("a.in","r",stdin); scanf("%d",&n);int a,b; for(int i=1;i<=n;i++) { scanf("%d",&a); memset(fst,0,sizeof(fst));tot=0; for(int j=1;j<=a;j++) { scanf("%d",&b); if(b) comb(j,b); } for(int j=1;j<=a;j++) { dfs(j,0);hash[i][j]=f[j]; } sort(hash[i]+1,hash[i]+a+1); for(int j=1;j<=i;j++) { bool flag=true; for(int k=1;k<=a;k++) if(hash[j][k]!=hash[i][k]) { flag=false;break; } if(flag==true) { printf("%d\n",j); break; } } } return 0; }
刷題總結——樹的同構(bzoj4337 樹上hash)