c 城將要舉辦一系列的賽車比賽。在比賽前,需要在城內修建 mm 條賽道。
c 城一共有 nn 個路口,這些路口編號為 1,2,…,n1,2,…,n,有 n-1n−1 條適合於修建賽道的雙向通行的道路,每條道路連線著兩個路口。其中,第 ii 條道路連線的兩個路口編號為 a_ia**i 和 b_ib**i,該道路的長度為 l_il**i。借助這 n-1n−1 條道路,從任何乙個路口出發都能到達其他所有的路口。
一條賽道是一組互不相同的道路 e_1,e_2,…,e_ke1,e2,…,e**k,滿足可以從某個路口出發,依次經過 道路 e_1,e_2,…,e_ke1,e2,…,e**k(每條道路經過一次,不允許調頭)到達另乙個路口。一條賽道的長度等於經過的各道路的長度之和。為保證安全,要求每條道路至多被一條賽道經過。
目前賽道修建的方案尚未確定。你的任務是設計一種賽道修建的方案,使得修建的 mm 條賽道中長度最小的賽道長度最大(即 mm 條賽道中最短賽道的長度盡可能大)
noip的題真的是越來越難啊。。。
首先容易看出是個二分。但是看出來還不夠,這題檢驗就比較噁心,我沒想出來(太菜了)。
一開始的想法是計算出乙個根下所有點對的路徑長,然後貪心地每次把滿足二分答案的路徑加進去,結果寫完之後自己證偽了這個貪心。
如果這題沒注意到乙個至關重要的點,是很難寫下去的:
對於一顆子樹,至多存在一條乙個端點在這顆子樹、另乙個端點在另一顆子樹的路徑。這是由於一顆子樹的根節點只有乙個父親,也就是說,子樹的根節點到它父親只存在一條邊。
所以我們只要想個辦法把某個二分答案下一顆子樹內部最多能形成的路徑統計出來。這個東西肯定要自底向上得出,顯然一顆子樹的路徑條數取決於它所有子樹的路徑條數總和,再加上一些經過這顆子樹根節點的路徑(也可能沒有),經過根節點的路徑又分為兩種情況,一種是終點在另一顆子樹種,一種是終點就是根節點。
考慮乙個類似樹形dp的東西,方便自底向上統計。
我們要統計兩個東西:路徑的長度、路徑的數量。
路徑的長度可以推出路徑的數量,因此我們只在dp(似乎不是dp)陣列記乙個穿過子樹根節點的路徑長度即可。
若要組成一條穿過某顆子樹根節點的路徑,必然是要合併兩條穿過它某兩個兒子的路徑。我們考慮這樣乙個貪心:一定是要先合併出盡可能短的滿足當前二分答案的路徑。所以我們肯定要先拿最短的那條穿過根的路徑去匹配另一條盡可能短的、使得它們長度之和滿足二分答案的路徑。
若要組成一條終點是根節點的路徑,我們肯定也是選擇那些盡可能短的滿足二分答案的路徑。所以在合併路徑之前,我們先看這個子樹是否存在這樣的路徑,存在就盡早把它統計上。
在上述過程完成後,我們還要選出一條路徑穿過根節點,跟其它子樹相連(或者僅與父親節點)。還是那個貪心原則,我們拿出沒有統計過的最長的一條路徑貢獻上去,這樣就能使得其它子樹中的路徑用的盡量少。
說實話我還是不太相信這個貪心是正確的,考場上我更有可能寫個搜尋。
#include#include#include#include#include#include#include#include#include#include#define ll long long
#define n 500010
using namespace std;
inline int read()
while(c>='0'&&c<='9')
return x*f;
}struct recg[n<<1];
int head[n],tot,n,m,res,q[n],tag[n],dp[n];
inline void add(int x,int y,int val)
inline void check(int x,int fa,int lim)
int tail=0;dp[x]=0;
for(int i=head[x];i;i=g[i].next)
sort(q+1,q+tail+1);
for(int i=tail;i>=1&&q[i]>=lim;--i)
res--,tail--;
for(int i=1;i<=tail;++i)
while(tag[pos]==x&&pos<=tail) pos++;
if(pos<=tail) tag[pos]=tag[i]=x,res--;
} }for(int i=tail;i>=1;--i)
if(tag[i]!=x)
}int main()
cout
}
洛谷P5021 賽道修建
話說去年為什麼暴力炸成了15.其實我現在都不會做,參考的一位p黨大佬的題解,寫成了c 版而已 附註了一些關鍵部分的細節 總之現在弄懂了qwq includeusing namespace std const int maxn 1e6 10,maxm 2e6 10,inf 1e8 int bg max...
洛谷 P5021 賽道修建(樹上貪心)
首先介紹乙個東西 multiset。它可以看成乙個有序的序列,且允許存在重複的數,並支援logn的時間插入和刪除。其他 看到題面,首先想到的是二分答案。二分第m條的長度,判斷的話就看是否至少存在有m條路徑,使得路徑長度大於等於mid。怎樣每次找的都是盡可能大的呢?那就得在樹上貪心。貪心策略 對於經過...
P5021 賽道修建 NOIP2018
傳送門 考場上把暴力都打滿了,結果檔案輸入輸出寫錯了.當時時間很充裕,如果認真想想正解是可以想出來的.問你 長度最小的賽道長度的最大值 顯然二分答案 考慮如何判斷是否可行 顯然對於乙個節點,它最多只能向父親傳一條路徑長度 那麼其它路徑的合併只能在子樹間進行 貪心一波,如果一段路徑在子樹就可以合併出合...