這篇要來聊聊生成樹,在競程最常看到的生成樹題目,除了最小生成樹相關的之外,應該就是計數了。最小生成樹在這一篇聊過,這裡主要就是談談計數。計數就是計算某種東西的數量,本質上就是要能夠和 一一對應 (或 bijection) 而已。國高中的計數就只是算算排列組合數、要分成幾堆之類而已
然而,在樹的計數,因為樹本身的結構很特殊,計數並不是一件簡單的事情。這類關於樹的競程題非常少見,但是每次見到鐵定是難題,尤其那些會跟 Combinatorics 一起出現的怪東西們,更是令人頭痛
這篇筆記會以生成樹作為切入點,來聊聊 Cayley's Formula、Prüfer Code 與克希荷夫的矩陣樹定理,並提供三種證明 Cayley's Formula 的方法
由於有些東西真的太難了,可能不會講要怎麼證明 反正競程能用就好
通常我們會討論生成樹,都是在一張一般的圖上討論。如果是樹的話,討論其生成樹沒什麼意義,因為樹的生成樹就是自己
若一棵樹 是一張連通圖 的子圖,且 (即 擁有所有 的節點),則稱 為一棵生成樹
下圖就是上圖的生成樹
深度優先搜尋 (DFS) 會訪問圖上的所有節點。事實上將走訪路徑保留後,可以連接所有節點形成一顆生成樹
相同地,BFS 也後產生一顆生成樹。此生成樹會有一個性質 : 根節點所有其他點的距離為最短
對於一張帶權圖,若利用 Dijkstra's algorithm,由於一定會遍歷整張圖的所有節點,因此肯定會形成一棵生成樹。而如果將出發點 視為根,那麼 到所有點的路徑邊權總和最小 (俗稱路徑最短)
上面介紹完生成樹,可以得知一張圖的生成樹可以有很多種,但是具體來說有幾種呢? 既然圖是一種有限結構,那生成樹的數量也應該是有限的吧! 那具體來說是幾種呢?
直接算真的非常困難,所以我們可以先把所有的樹都編成一組 Prüfer Code,說明 Prüfer Code 與生成樹是 bijection。如此一來,算 Prüfer Code 的數量就等於數生成樹的數量。這樣就可以導出一個公式 (Cayley's Formula) 來解決這個問題
備註 : 這裡我們討論的節點都有數字標籤
一棵樹 。其中,節點集合
一個由節點標籤組成的序列 。其中,序列長度為
給一張 個節點的樹、:
刪除 、:
刪除 、:
刪除 、:
刪除 、:
刪除 、:
刪除 、:
刪到只剩 個節點就可以停了
輸出 : 序列
藉由這個演算法,可以知道每棵生成樹都會對應一個序列,接下來你可能會好奇這個序列是否代表唯一的生成樹,事實上答案是肯定的。下一段 Cayley's Formula 的證明中,會證明這件事
對於具有標籤 的節點集合,總共有 棵樹 ()
當 時,樹的數量為
注意 : 雖然三棵樹是同構 (isomorphism),但因為編號不同,所以要視為三種不同生成樹
首先推一下 Prüfer Code 總共有多少種可能 :
已知 Prüfer Code 長度為 ,序列每個位置可以填入 種數字標籤,因此共有 種可能
接下來使用歸納法證明 Prüfer Code 與生成樹是 bijection :
令 為序列的集合, 是大小為 的節點集合
Basis step : 當
存在一個 節點的樹,其序列長度為 ,是唯一的空序列
Induction step : 當
假設給定一個節點集合 與序列 ,存在一個唯一的 使得
令第一個被刪除的葉節點叫 。根據演算法,我們會紀錄 在序列中,也就是 的唯一鄰居,因此 存在一條邊 。在刪除 後,樹的節點集合變成 ,然後序列
根據歸納假設,僅存在一棵節點集合為 樹 使得
因為每棵序列為 的樹都有加上 ,所以僅存在最多一個可能使 。再者,將 加上 會形成節點集合 與序列 ,所以這就是那唯一的可能
由於樹和 Prüfer Code 是 bijection。Prüfer Code 的數量是 ,那麼樹的數量也是
給定一些整數 ,加起來為
總共有 棵節點集合為 的樹使每個節點 都有度數為
在序列中,每個元素 都會出現 次,因為在演算法中我們會把與其相連的葉節點都刪掉,直到 成為葉節點或是成為最後兩個的其中一個節點。因此,在長度為 的序列中,每個元素 都出現了 次。當我們隨便亂生一個串,總共會有 個序列,但其中有重複的,所以要除掉 次
其實也可以寫成 multinomial coefficient 的形式
給定 個連通塊的大小 ,總節點數為
讓圖連通的方法數 :
我不會,但這篇有寫 (因為他重複使用變數,而且步驟有點跳,所以我看不懂)
因為最近學了生成函數 (generating function),所以給出用生成函數推導的方法
計算 個點上有根樹的數量叫 ,若移除了根並觀察子樹,會得到一個遞迴式
天啊這要怎麼觀察
乘上 (因為我們要搞生成函數),然後整理一下
這就會是我們的生成函數 囉!! (最下面的等式是用泰勒展開搞回去)
接下來把有 的都放到左邊
因為它長的很像拉格朗日反演的樣子,所以我們弄弄看拉格朗日反演公式
然後再平移一下多項式
因此,
最後,因為我們算的是有根的樹,但答案應該要是沒有根的樹,因此要除掉一個
得到 為有標籤的節點所能形成的樹的數量
克希荷夫的矩陣樹定理可以求出給定一張圖 的生成樹數量。若要理解其方法,需要先知道要怎麼用矩陣玩圖論。這種用線性代數玩圖論的領域叫做 Spectual Graph Theory
首先,這裡的圖都假設連通,否則沒辦法討論其生成樹
這應該資料結構就學過了,放在數學裡也是一樣
鄰接矩陣 是一個方陣。對於每個 代表點對 之間的邊數,其中有幾種性質
度數矩陣 是一個對角矩陣。對於每個節點 , 代表其度數,除了對角以外的部分皆為 。其中,自環對度數貢獻為
拉普拉斯矩陣
有學過向量微積分的話應該很熟悉拉普拉斯運算子,就是梯度的散度那個,它本質上就是相鄰減自身,通通加總,並除掉一個分母。拉普拉斯矩陣也有相似的概念,只是不知道為什麼反過來了
令 為一個方陣, 的 minor 是一個消除第 列第 行後的矩陣的行列式
在上一個定義中, 的 cofactor 為
令 為某張無向圖的拉普拉斯矩陣,則所有 的 minor 套上絕對值後都相同
令 為某張無向圖的拉普拉斯矩陣,則所有 的 cofactor 都相同
如下圖,收縮後的圖
給定一張無向圖 ,對於任何節點 , 的生成樹數量為
證明有很多版本,這裡採用我比較看得懂的版本,因為太複雜所以大概說一下就好
可能有點不太嚴謹
因為圖都是連通的,考慮一條邊 ,當我們在找生成樹的時候, 要嘛在樹上要嘛不在 (廢話)。若 在樹上,則我們不用考慮他,可以使用邊收縮並找出 的生成樹數量。若 不在樹上,相當於我們忽略它,因此就是要找 的生成樹數量。因此,可以得到 有點像是對圖做遞迴的感覺
我們可以對邊做歸納法
Basis case : 整張圖只有兩點與他們之間的 條邊
,所以
歸納假設 : 假設對 與 ,定理都為真
Inductive step : 我們希望證明定理在 時為真
將兩節點 特別挑出來,令 為度數, 為 之間的邊數,則我們可以整理出以下行列式。其中, 與 是紀錄 的相關訊息, 是拉普拉斯矩陣中沒動到的其他部分
當然我們也可以整理出 的行列式
還有 的行列式
根據引理 1, 2,取 也會是答案。為了結束歸納法,我們說明
也就是
這可以用 Laplace expansion 展開來證
最後,根據歸納假設,因為定理在 與 為真,因此在 也為真
所以
下圖總共有八種生成樹
當然我們也可以用矩陣樹定理算出來
將第 行第 列刪掉得到
Cayley's Formula 的條件與矩陣樹定理的條件有點不同
若把矩陣樹定理給的 換成完全圖 ,那就相當於變成 Cayley's Formula 的條件,所以就可以計算拉普拉斯矩陣
然後再找出 cofactor (刪哪行哪列都一樣),其中 cofactor 的大小只有
這個鬼東西並不好求,所以可以考慮找 eigenvalue。其中,我們需要用到以下性質 :
令 是這個 矩陣,考慮 是一個所有元素都是 的矩陣
答案就這樣莫名其妙地算出來了
這些東西一出現就肯定是難題,通常跟什麼 generating function、stirling numbers 等等噁心的東西一起出現,所以建議去學 Combinatorics 或是讀 Generatingfunctionology (一本書)
OnlineJudge 10843 - Anne's game (Cayley's formula 裸題)
Codeforces 156 D. Clues (拓展 Cayley's formula)
CSES Prüfer Code (Prüfer Code 裸題)
Codeforces 917 D. Stranger Trees (做法很多,要想一下)
Codeforces 1762 E. Tree Sum (動動腦)
CSES Functional Graph Distribution (Cayley's formula,好像也要用 Stirling number,神奇的數學題)
ABC 253 Ex - We Love Forest (矩陣樹定理 + 位元 DP)
ABC 323 G - Inversion of Tree (矩陣樹)
Atcoder jsc2021 G - Spanning Tree (矩陣樹)
ShanC 程式競賽筆記
作者: ShanC
更新: 2025/6/25