openlayers地圖覆蓋物overlay詳解
\(\operatorname{prufer}\)序列
定義
一種無根樹上的數列。
由頂點標號的無根樹轉化而來。且對於一棵確定的無根樹,其對應的\(\operatorname{prufer}\)序列也是唯一確定的。
構造
無根樹到序列
有兩個基本操作:
- 找到一個編號最小的葉節點,不妨記為\(x\)。
- 把與\(x\)相連的節點加入序列,然後把\(x\)從樹中刪除。
重複這兩個操作,直到整棵樹剩下2個節點。
容易知道,我們加入序列的數共有\(n-2\)個,這\(n-2\)個數構成的序列就是\(\operatorname{prufer}\)
舉個例子,對於下圖這棵樹:
對它執行上述操作:
- \(x=4,p=\{2\}\)
- \(x=5,p=\{2,3\}\)
- \(x=3,p=\{2,3,1\}\)
- \(x=6,p=\{2,3,1,2\}\)
那麼對於這棵有6個節點的節點標號無根樹,我們就得到了長度為4的\(\operatorname{prufer}\)序列\(\{2,3,1,2\}\)
程式碼實現:
inline void Tree_Prufer() { for (ri i=1;i<n;++i) f[i]=read(),++ind[f[i]]; for (ri i=1,j=1;i<=n-2;++i,++j) { while (ind[j]) ++j; p[i]=f[j]; while (i<=n-2 && !(--ind[p[i]]) && p[i]<j) p[i+1]=f[p[i]],++i; } for (ri i=1;i<=n-2;++i) ans^=(1ll*i*p[i]); printf("%lld",ans); }
序列到無根樹
三個基本操作:
- 取出序列最前面的元素,記為\(x\)。
- 取出在點集中且當前不在序列中的最小元素。
- 在\(x,y\)間連邊。
顯然最後點集中還會剩下2個點( \(n-(n-2)=2\) ),把這兩點連一條邊。
基本就是上面的逆操作,程式碼如下:
inline void Prufer_Tree() { for (ri i=1;i<=n-2;++i) p[i]=read(),++ind[p[i]]; p[n-1]=n; for (ri i=1,j=1;i<n;++i,++j) { while (ind[j]) ++j; f[j]=p[i]; while (i<n && !(--ind[p[i]]) && p[i]<j) f[p[i]]=p[i+1],++i; } for (ri i=1;i<n;++i) ans^=(1ll*i*f[i]); printf("%lld",ans); }
性質與相關結論
性質:\(\operatorname{prufer}\)序列與無根樹唯一確定對應。
結論1:度數為\(d[i]\)的節點恰好會在\(\operatorname{prufer}\)序列中出現\(d[i]-1\)次。
簡單證明:
先考慮最簡單的情況,該節點度數為1,那麼它會被直接刪掉,也就是出現的次數為0;
將此思想拓展,若該節點度數 \(d[i]\) 大於1,那麼它有邊直接相連的節點(除了它的父親)(這個節點數也就是它的度數)每被刪掉一個,它就會在序列中出現一次。所以共出現 \(d[i]-1\) 次。
結論2:\(n\)個節點的完全圖的生成樹個數為\(n^{n-2}\)。
簡單證明:
\(n\)個點的無根樹對應的\(\operatorname{prufer}\)序列的長度為\(n-2\),這\(n\)個原來的節點標號均可能在這\(n-2\)個位置上出現,也就是說,有\(n^{n-2}\)種可能的\(\operatorname{prufer}\)序列。每個\(\operatorname{prufer}\)序列都可以對應一棵生成樹。
結論3:對於給定度數\(d[i]\)的無根樹,它的\(\operatorname{prufer}\)序列有
\[\large \frac{(n-2)!}{\prod_{i=1}^{n}(d[i]-1)!} \]種情況。
簡單證明:
由結論1可得:
\(\Rightarrow\) 求\(d[i]-1\)個\(i\)的可重全排列個數。
*可重全排列:全排列個數 除以 重複元素內部全排列個數
例題待補。