P2491 消防 P1099 樹網的核

2022-05-30 17:54:09 字數 981 閱讀 6924

雙倍經驗,雙倍快樂。

在乙個樹上選擇一段總長度不超過\(s\)的鏈使所有點到該鏈距離的最大值最小。

輸出這個最小的值。

define:以下\(s\)指鏈或鏈長。

證明一下\(s\)一定處於直徑上。假設它不在直徑上,一定存在直徑的其中乙個端點到\(s\)的距離大於現在所處支鏈的最大距離。所以\(s\)不在直徑上一定不優。

於是我們找到直徑並記錄下直徑上的所有點。

然後,我們列舉直徑上的每乙個長度小於\(s\)的最長區間(最長原因顯然,因為長度越短答案肯定不會更優),並計算此時的答案,對於每乙個區間的答案取min即可。

考慮計算每個區間的答案。我們把直徑拉出來,用兩個指標\(l\)和\(r\)從左向右遍歷這個直徑,\(s\)即為\(l\)到\(r\)。考慮此時這個區間的答案即為\(l\)到\(r\)中每個點\(i\)的子樹中最深的點的距離(我們設為\(h_i\))(注意這裡的子樹是不包括直徑的,即子樹中所有的點都屬於支鏈)和\(l\)到直徑左端點的距離(設為\(ls\))和\(r\)到直徑右端點的距離(設為\(rt\))的最大值。原因顯然。

那麼我們可以預處理出\(h_i\),並在遍歷直徑的時候用單調佇列維護\(h\)的最大值,然後用這個值與\(ls\)和\(rt\)的最大值更新答案(取最小值)即可。

(學會了乙個新單詞diameter,意思是直徑,重音在|a|上)

#include#include#include#include#includeusing namespace std;

inline int read()

namespace star

int d[maxn],mx,fa[maxn],diam[maxn],tot,sum;

void dfs1(int x,int f,int &dia)

printf("%d",ans);

} inline void work()

}signed main()

P1099 樹網的核

這裡是o n 2 的做法 首先可以證明,對於每一條直徑,求出的偏心距是一樣的 怎麼證明?顯然 我不會 怎樣求樹的直徑?簡單。貪心 在一條直徑上,顯然選擇的路徑越長越好 實現 首先求出樹上所有點之間的距離 n 2 一直dfs就行 然後找出直徑及直徑經過的點 最後在直徑上貪心的取即可 include i...

洛谷 P2491消防 解題報告

某個國家有n個城市,這n個城市中任意兩個都連通且有唯一一條路徑,每條連通兩個城市的道路的長度為zi zi 1000 這個國家的人對火焰有超越宇宙的熱情,所以這個國家最興旺的行業是消防業。由於 對國民的熱情忍無可忍 大量的消防經費開銷 可是卻又無可奈何 競選的國民支援率 所以只能想盡方法提高消防能力。...

洛谷P1099 樹網的核

題目 對於這種題目描述比較長的題,可以考慮簡化題意。簡化後的題意 給定一棵帶邊權無根樹 在其直徑上求出一段長度不超過s的路徑f,使得離路徑距離最遠的點到路徑的距離最短。求最短距離。根據題目範圍,直接暴力floyd求多源最短路徑。然後 n 2 求出直徑和直徑端點。搜尋求出直徑上的點。然後再暴力找出所有...