無向連通圖的生成樹個數

對於一個無向連通圖來說,它可能有很多生成樹,那麼如何求得它的生成樹個數呢?

首先給出一個非常一般的計算方法 -- 矩陣行列式法

對於任何一個頂點數爲n的無向連通圖,我們列出一個矩陣。

矩陣的規則是:

1、在主對角線上的元素爲此節點的度數

2、對於其他位置上的元素Matrix(i,j) { i != j },

 (1) 如果節點i和節點j連通,則Matrix(i,j)的值爲-k,其中k值爲節點i到節點j的平行邊個數。如果此圖是一個簡單圖,即任意兩點間不存在平行邊,那麼這個值就爲-1.

 (2) 但如果節點i和節點j根本不連通,則Matrix(i,j)的值爲0。這樣的一個矩陣Matrix就會很容易的用O(n^2)的複雜度建立。接下來如何求得這個無向連通圖的生成樹個數呢。直接給出定理:撤去任意一個節點的信息,求出剩下的(n-1)*(n-1)矩陣的行列式,此值即爲這個無向連通圖的生成樹個數。複雜度爲O(n^3) 下面給出一個例子: 此圖上的節點數爲n = 8,則根據上述方法,我們要列出一個8*8的矩陣,然後再消去一行,算出其行列式。 矩陣爲:(8*8) 2 -1 -1 0 0 0 0 0 -1 1 0 0 0 0 0 0 -1 0 3 -1 -1 0 0 0 0 0 -1 4 0 -1 -1 -1 0 0 -1 0 1 0 0 0 0 0 0 -1 0 1 0 0 0 0 0 -1 0 0 1 0 0 0 0 -1 0 0 0 1 假如去掉第1個節點的信息,那麼也就是去掉第一行和第一列,則矩陣變爲:(7*7) 1 0 0 0 0 0 0 0 3 -1 -1 0 0 0 0 -1 4 0 -1 -1 -1 0 -1 0 1 0 0 0 0 0 -1 0 1 0 0 0 0 -1 0 0 1 0 0 0 -1 0 0 0 1 上述圖的生成樹個數可以通過求上面這個7*7矩陣的行列式算出。 具體證明可以參考 Algorithmic graph theory / Alan Gibbons Gibbons, Alan (Alan M.)

下面來看兩個問題:

問題一: TN's Kingdom I - Establishment http://acm.pku.edu.cn/JudgeOnline/problem?id=2819 這個問題其中比較重要的一步就是求一個K階完全圖的最小生成樹的個數。通過上述方法則可以很容易的求出其個數爲n^(n-2)個。在上述的那本參考書中還有另一種證明方法,組合數學的方法,也可以參考參考。

問題二:Spanning trees in a fan http://acm.hit.edu.cn/ojs/show.php?Proid=100322&Contestid=42 這個問題是給定一個特殊規定的無向連通圖,求其生成樹的個數。此問題當然可以用上述矩陣法求解,但是其點可以達到1000,那麼 O(n^3)的複雜度還是很難接受的。但是此題非常簡單,可以用很容易的遞推搞定,也可以用上述的方法檢驗。 具體方法如下: 設ans[i]表示有i個節點時,此圖生成樹的個數。那麼我們只要找到其第i+1個節點插入後,生成樹如何變化就可以了。如果想把第i+1個節點也加入生成樹的話,那麼只有三種連入前i個節點生成樹的方案。 1、將i與i+1節點相連 2、將0與i+1節點相連 3、將0與i+1,i與i+1都相連(這樣會多一條邊) 情況1和情況2非常好處理,都分別等於ans[i],所以遞推式先可寫爲ans[i+1] = 2*ans[i] + N(情況3);那麼情況3又如何計算呢,其實也很簡單,由於情況3中要加入2條邊,那麼也就是說前面的模型必須要有i-1條邊(因爲0-i共有i+1個節點,所以生成樹需要i條邊,但是要少一條,所以爲i-1條邊)。再考慮情況3中連這兩條線有什麼用處呢,很容易想到,這兩條邊把節點0和節點i相連了起來,如果說以前的模型中已經連通這兩點,那麼就會產生衝突(0 - i必然有環,不爲樹)。那麼也就是說要想在原來的模型上加上這兩條邊,原來的模型中節點0和節點i之間必然不連通,那麼遞推式中的N(情況3)也就是節點0與節點i不連通的模型的個數。也就是說可以取k ( 1 <= k < i ),並且使0,1,2,……,k都連通成樹,然後k+1,k+2,……,i都連通並且和0不連通。 所以很容易的計算出N(情況3)=SUM{ans[k]} (1 <= k < i)。整個遞推公式就完成了,答案爲: ans[i+1] = 2*ans[i] + SUM{ans[k]} (1 <= k < i); 這樣的公式我們還是很滿意,可以用O(n)的複雜度生成答案表,空間複雜度也是O(n),但是要存儲前i項ans[]和。 其實我們更可以進一步遞推,使得式子變爲更簡單。可以猜想加數學歸納法證明: ans[i+1] = 3*ans[i] - ans[i-1]; 這樣的式子是我們能得到的最滿意的式子了。 通過上面的兩道題,我們可以看出,生成樹個數的問題要看規模,在O(n^3)複雜度允許的情況下,可以使用矩陣法,如果複雜度不允許的情況下,我們可以直接找出其遞推關係。 以上算法也正在研究中,如果有什麼不對之處,請大家批評指正:)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章