1. 程式人生 > >最小樹形圖入門總結

最小樹形圖入門總結

求解最小樹形圖最小權值一般使用演算法為朱劉演算法.

原理入門推薦部落格:https://blog.csdn.net/qq_34731703/article/details/53965684

ps:該部落格使用模板為鄰接矩陣實現,便於理解,但是在做題時鄰接矩陣初始化耗時太多,我們需要改成前向星的儲存方式.

關於模板: 用前向星實現的朱劉演算法網上有許多模板,這裡放個我覺得比較優秀的模板:https://www.cnblogs.com/vongang/archive/2012/07/18/2596851.html

關於題目: 

①:模板題入門POJ - 3164  tips:對於此類模板題,建議照著部落格手敲一遍.加強對演算法的記憶

②:定根與不定根的思考:

在第一個模板題裡面,是給定了最小樹形圖的根的.但是我們做題時會發現很多題沒有給定我們根,此時我們需要根據不同情況來進行構造: 

情況1:圖不需要自己額外建(即題目給好了N個點,M條邊),只是沒有給定根.如 HDU - 2121

對於此種情況,我們需要額外新增一個點,作為根,並從這個根向每個節點都連線一條邊,而邊的權值需要比其他所有邊的權值加起來更大,表明這些點都有可能是最小樹形圖的根, (至於為什麼權值應該是所有邊權值加起來,個人是這樣認為的:首先,權值不能為0,權值為0的話最小樹形圖就始終會是全部取與虛根相連的邊構建成的最小樹形圖,而當權值取其他所有之和時,可以更加方便的判斷是否能生成最小樹形圖),在得出答案後減去虛根相連邊的權值即是答案.

情況2:圖需要自己建,同時也沒有給定根,如HDU - 4009.

對於這種情況我們需要根據題目情況建立虛根,然後讓這個根與你構建的初始點進行相連.


對應這個題,其初始點就可以設為這n個點,然後權值為在這個點建井的花費,而對於它給的其他邊,我們直接在對應的兩個點上建邊即可,然後跑一下朱劉演算法,就可得出答案.

所以,在遇到這種情況的時候,我們應該根據題目要求,讓虛根和你建的邊產生聯絡.

③: 合理的建圖方法:

例題:HDU - 4966  .

首先,這個題給定我們n門課程和m個輔導班,然後給定我們每門課程需要達到的等級,對於每個輔導班,它會告訴我們等級在a課程等級達到了b即可花費e讓c課程的等級達到d,問每門課程達到對應等級最小的花費.................................................................................

首先,我們可以想到可以把每門課程的每個等級都看成一個點,然後我們可以知道對於同一門課程,高等級向低等級走花費為0.

因此我們可以直接用每個課程每個等級建圖,然後將每門課程的高等級向低等級連一條權值為0的邊.對於輔導班,我們可以直接連線對於的課程和等級...那麼對於虛根呢..其實我們很容易想到.虛根應該與每門課程等級為0的點相連.權值直接設計為0即可.

建議:在做完上面這個例題後,可以做一下這個同類型的題 HYSBZ - 4349.思考一下這個題應該怎麼建圖...

④:一些其他題UVA - 11865 ---->二分加最小樹形圖

CodeForces - 240E ------->最小樹形圖+路徑輸出 (自己獨立思考出這個題就應該能完全掌握最小樹形圖)

做完上面這些,應該就算是入門了吧..

tips:感覺最小樹形圖的題是很貼切圖論的關鍵在於建模這個核心要點的.建圖一定要貼切題意,最好不要建無用邊,不然複雜度會加大很多.