1. 程式人生 > 其它 >Prufer序列學習筆記

Prufer序列學習筆記

\[\huge \rm Prufer~序列 \]
\[\Large \rm Prufer~序列的定義 \]

\(\quad\rm Prufer\) 序列可以將一顆結點數為 \(n\) 的有標號無根樹用一個長度為 \(n-2\),值域為 \([1,n]\) 的數列唯一表示,即有標號無根樹和 \(\rm Prufer\) 序列呈雙射關係。

\(\quad\)具體來說,有標號無根樹的構建方式如下 :

  • 選擇一個編號最小的葉子節點,並將其刪除。
  • 將這個葉子節點所連線的點的編號加入 \(\rm Prufer\) 序列中。
  • 重複以上步驟 \(n-2\) 次,直到樹上只剩下 \(2\) 個點。

\(\quad\)這是某一顆點數為 \(n\) 的有標號無根樹的 \(\rm Prufer\)

序列的構造過程:


\[\Large \rm Prufer~序列的求法 \]

\(\quad\)由其過程,顯然有一個使用堆優化的 \(\Theta(n\log n)\) 做法,但 \(\rm Prufer\) 序列其實可以線性構造。

\(\quad\)記錄所有點的度數和一個指標 \(p\) 指向編號最小的葉子節點,進行以下操作 :

  • \(p\) 指向的結點刪除,檢查是否出現了新的葉結點。
  • 如果產生了新的葉結點,記其編號為 \(x.\)\(x>p\),則不做任何操作,否則將其刪除,並檢查刪除 \(x\) 以後是否出現了新的葉結點,重複這一步操作直到沒有產生新的葉結點或新產生的結點編號大於 \(p.\)
  • \(p\) 自增直到遇見下一個葉結點為止。
  • 重複以上操作直到結點數為 \(2\) 可以得到這棵樹的 \(\rm Prufer\) 序列。

\(\quad\)可以發現,在演算法流程中,每條邊只在其連線的外層結點被刪除時被遍歷過一次,並且 \(p\) 單調遞增,樹中的節點數單調遞減,所以每個點也只被遍歷過一次。

\(\quad\)總時間複雜度 \(\Theta(n).\)


\[\Large \rm Prufer~序列還原有標號無根樹 \]

\(\quad\)顯然還是有一個堆優化的 \(\Theta(n\log n)\) 做法。

\(\quad\)從前到後列舉 \(\rm Prufer\) 序列中的每一個數,維護不在序列中的結點編號的最小值。顯然不在序列中的是葉子節點,並且其最小值為最後一個加入的,於是將其與當前列舉的序列中的數連邊。連邊後若序列中已沒有列舉的這個數,那麼將其踢出序列作為新的葉子結點。

\(\quad\)考慮以與之前構造 \(\rm Prufer\) 序列相同的方法構造線性做法。

\(\quad\)記一個指標 \(p\) 指向不在序列中的最小結點,如果將其連向序列中列舉的位置,並將列舉的位置刪除。序列中沒有這個結點了,那麼如果被刪除的結點比 \(p\) 小,直接將其與現在序列中列舉的數連邊後將其刪除,重複操作。如果這個結點的值大於 \(p\),那麼不用管它,在後面它一定會被列舉到。

\(\quad\)顯然,這種演算法的時間複雜度為 \(\Theta(n).\)


\[\Large \rm Prufer~序列的應用 \]

\(\large \rm Cayley~公式\)

\(\quad\)完全圖 \(K_n\)\(n^{n-2}\) 顆生成樹。

\(\quad\)證明方法很多,其中最簡單的應該是利用 \(\rm Prufer\) 序列。

\(\quad\)考慮到任何一個長度為 \(n-2\)\(\rm Prufer\) 序列唯一對應一顆大小為 \(n\) 的有標號無根樹,於是考慮計算長度為 \(n-2\)\(\rm Prufer\) 序列的數量,又因為其值域為 \([1,n]\),故總方案數為 \(n^{n-2}.\)

\(\large \rm 限定度數的有標號無根樹計數\)

\(\quad\)求有 \(n\) 個結點,且第 \(i\) 個結點的度數為 \(d_i\) 的有標號無根樹的數量。

\(\quad\)考慮到一個點的度數為其在 \(\rm Prufer\) 序列中出現次數 \(+1\),於是對於一個度數為 \(d_i\) 的點,其在 \(\rm Prufer\) 序列中的出現次數應為 \(d_i-1\),故存在這樣的有標號無根樹當且僅當 \(\sum_{i=1}^n d_i-1=n-2\),並且這樣的樹的數量為 :

\[\dbinom{n-2}{d_1-1,d_2-1,\cdots ,d_n-1}=\frac{(n-2)!}{(d_1-1)!(d_2-1)!\cdots (d_n-1)!} \]