【校內模擬】【18-10-16】 華萊士 【環套樹】

(拖更N天終於想起來我還有博客
(校內模擬的題面&代碼聯賽後解除封印~)

題解

1.0 認(hu)真(luan)分析

這道題直到考試完我都沒怎麼看懂……(太弱了)

其實題意非常簡單:在保證每個點只有入度爲1的情況下,計算出聯通所有點所需的最小代價。

如果這題給的不是無向邊而是有向邊,我們自然可以想到Kruskal一波解決。問題就在於,這是有向邊,而我們需要的是一個聯通圖。

那麼,如果使用Kruskal求出最小生成樹,最後再加上一條花費最小的邊,使得樹上出現一個環,似乎就能解決這個問題了?

很遺憾,這個算法是錯的,在考場上只能得到50分(實際上是因爲數據水了)

1.1 繼續分析

首先我們弄清楚一個概念:環套樹。

顧名思義,環套樹還真就是一個環+一棵樹的結構。那麼運用在這道題裏,我們實際上就是求給定圖中的最小環套樹.

嗎?

僅僅這樣還不夠,因爲可能圖中存在多個環套樹,也許還有零散的點構成樹,因而最後我們求得的實際上是一個環套樹森林。

那麼在這個求得的過程中,我們還是考慮Kruskal的加邊方式,也就是按權值從小到大依次加邊。那麼這其中肯定會牽扯到合併兩個聯通塊的問題,這又該怎麼解決呢?

下面的解說(又)引自神仙ZXY的博客

顯然合併環套樹與環套樹是不夠優的。
簡單樹和環套樹合併後的圖是環套樹。
簡單樹與簡單樹合併後的圖仍然是簡單樹。
簡單樹內部加邊就成了環套樹。
只需要考慮上面四種情況,如果最後有節點不在環套樹森林中,肯定無解。

爲了查詢每個聯通塊自身的屬性,我們可以在並查集的根節點上進行維護。這樣一來,只需要在Kruskal的合併部分加上幾個關於聯通塊屬性的特判就可以了。

總結

有的時候,當我們發現一個問題與另一個問題相近,就意味着我們只需要對原有算法進行些許改動,讓它適合這道題就可以了。因而在考試時不要輕易否決每一個念頭,說不定那就是解出這道題的關鍵呢~

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