洛谷 P5021 賽道修建(樹上貪心)

2022-04-06 17:38:00 字數 1262 閱讀 7556

首先介紹乙個東西:multiset。它可以看成乙個有序的序列,且允許存在重複的數,並支援logn的時間插入和刪除。(其他:

看到題面,首先想到的是二分答案。二分第m條的長度,判斷的話就看是否至少存在有m條路徑,使得路徑長度大於等於mid。

怎樣每次找的都是盡可能大的呢?那就得在樹上貪心。

貪心策略:

對於經過乙個點的賽道的構建方式有且只有兩種:

1.一條鏈直接作為賽道(如下圖中類似於紅色的構建方式)。

2.兩條半鏈拼成乙個賽道。

因此可以對於以u為根的子樹,先盡可能多的拼出賽道,同時在剩下拼不成整條賽道的情況下,選盡量長的傳給父節點,作為父節點半鏈的候選答案。

如何處理半鏈的拼接呢?把它放到multiset中進行維護,二分尋找最短的與當前長度的半鏈可以拼成整鏈的半鏈,如果找不到就一直取最大值,把最大的傳上去即可。

ac**(o2):

1 #include2 #include3 #include

4 #include5

using

namespace

std;

6int

n,m,tot,num;

7const

int n=50005

;8 multisetst[n];

9 multiset::iterator it1,it2;

10struct

nodeedge[n<<1

];13

inthead[n];

14void add(int u,int v,int

w)20

int dfs(int u,int fa,int x,int

dis)

29int maxx=0;30

if(st[u].size()==0) return

dis;

31while

(st[u].size())

40else maxx=max(maxx,w);41}

42return dis+maxx;43}

44bool check(int

x)49

intmain()

57int l=1,r=1e9;

58while(l

63 printf("%d"

,l);

64return0;

65 }

ac**(o2)

洛谷P5021 賽道修建

話說去年為什麼暴力炸成了15.其實我現在都不會做,參考的一位p黨大佬的題解,寫成了c 版而已 附註了一些關鍵部分的細節 總之現在弄懂了qwq includeusing namespace std const int maxn 1e6 10,maxm 2e6 10,inf 1e8 int bg max...

P5021 賽道修建 NOIP2018

傳送門 考場上把暴力都打滿了,結果檔案輸入輸出寫錯了.當時時間很充裕,如果認真想想正解是可以想出來的.問你 長度最小的賽道長度的最大值 顯然二分答案 考慮如何判斷是否可行 顯然對於乙個節點,它最多只能向父親傳一條路徑長度 那麼其它路徑的合併只能在子樹間進行 貪心一波,如果一段路徑在子樹就可以合併出合...

P5021 賽道修建 貪心 二分

c 城將要舉辦一系列的賽車比賽。在比賽前,需要在城內修建 mm 條賽道。c 城一共有 nn 個路口,這些路口編號為 1,2,n1,2,n,有 n 1n 1 條適合於修建賽道的雙向通行的道路,每條道路連線著兩個路口。其中,第 ii 條道路連線的兩個路口編號為 a ia i 和 b ib i,該道路的長...