定義
(圖片來自這篇文章)
-
基環樹: 有 \(n\) 個點 \(n\) 條邊的連通圖
-
外向樹: 每個點出度為 \(1\)
- 內向樹: 每個點入度為 \(1\)
找環
- \(dfs\)
- 拓撲排序
一般處理方法
因題而異,一般有兩種常用的
-
第一種是先斷掉環邊,把環上點當作根,處理每一棵子樹,再在環上處理,可能需要環形 \(DP\)。
-
第二種是選擇一條環邊斷掉,化成樹上問題,可能需要列舉斷邊,或者換根 \(DP\)。
具體還是看題吧
例題
- [ZJOI2008] 騎士
- 雙倍經驗
簡要題解
考慮一條邊連結的兩個點不能同時選,隨便找一條環邊\(u - v\)斷開,強制\(u\) 不選,強制 \(v\) 不選,兩種情況取 \(max\)
- [IOI2008] Island
求基環樹森林的直徑和,邊帶權
簡要題解
只考慮一棵基環樹
直徑可能過環,也可能不過環,兩種情況取最大值
把環找出來,先刪去環邊,找每棵子樹的直徑最大值
再考慮如果經過一段環邊,那麼就是經過環上兩點的路徑和這兩個點子樹內最長鏈之和的最大值
考慮如何處理這個環上問題
兩點間距離快速求解需要字首和,那麼答案可以寫成
\(max(len_i + len_j + sum_i - sum_j) (i > j)\)
也即
\(max(len_i + sum_i, len_j - sum_j) (i > j)\)
但是環上有兩個方向呢?
你發現另一個方向其實就是
\(max(sum + len_i - sum_i, len_j + sum_j) (i > j)\)
取 \(len_i + sum_i\) 的最值和 \(len_i - sum_i\) 的最值即可
- [NOIP2018 提高組] 旅行
簡要題解
\(m = n - 1\),是一棵樹,直接排序後按照 \(dfs\) 序輸出即可
\(m = n\),基環樹,發現環邊一定不會全走,可以列舉環邊斷開,比較字典序取最小的即可
- 加強版
\(n \leq 500000\)
題解
- Hobson 的火車
簡要題解
先考慮在樹上怎麼做
一個點會貢獻到一條鏈上
樹上差分
環上呢?
考慮每個點會貢獻到環上的一段,仍然可以對環進行差分處理