BZOJ1999 樹網的核
題意縮簡:
給你一個樹上偏心距的定義 讓你在某一條直徑上找一條長度不超過S的線段使得偏心距最小
樹上偏心距:樹上離某段線段最遠的節點的距離
樹上節點到線段的定義:節點離線段上最近點的距離
做題之前 我們先得出一個結論:在任意一條直徑上求出的最小偏心距都相等
證明:
如果僅有一條直徑 明顯成立.
如果有兩條及以上的直徑的話 因為直徑必定相交且中點重合(題目給出 也很任意證明)
所以在其中一條直徑上求最小偏心距的答案 必定是另一條直徑的某一個端點貢獻的 把這個兩個直接角色互換 答案不變
解法一:樸素(O(n^3))
枚舉某一條直徑上長度不超過S的線段(O(n^2))
然後再O(n)地直接得到當前情況的答案
解法二:貪心(O(n^2))
在樸素做法的基礎上 我們很容易知道 這個線段能盡量長就盡量長這樣根據定義擴充後的線段的偏心距會不大於原來的偏心距
所以我們在某一條直徑上直接枚舉長度為S的線段O(n) 再O(n)地直接得到當前情況的答案
解法三:二分答案(O(nlog(SUM)))
顯然 答案具有單調性 所以我們可以二分答案 然後O(n)或者O(1)地check (SUM為樹上所有邊長之和)
check:設當前二分答案值為mid 如果mid不小於直徑長度/2 則直接r=mid O(1)
反之 則找到離直徑兩端分別為mid的兩個點P與Q 連接這兩個點作為核 再O(n)得到最小偏心距 看是否大於mid
(可以證明 任意從P或Q到其最近的直徑一端分叉出去的子樹 其最遠點與P或Q的距離不會超過P與其最近的直徑一端的距離)
解法四:單調隊列O(n)
我們先求出一條直徑O(n)dfs直徑上的點得到一個數組d
d[i]表示從i點出發不經過直徑上的其他點能夠到達的最遠點的距離
然後直接搞一個單調隊列 維護長度為S時每段的答案O(n)
BZOJ1999 樹網的核