Luogu P2680運輸計畫(樹上差分 二分)

2022-05-01 01:27:13 字數 1703 閱讀 9741

題目鏈結

總體思路……怎麼說呢……是個暴力吧……

首先用倍增預處理出每條路徑的長度。  然後按長度把路徑排序。

然後二分答案。對於當前答案mid檢驗,怎麼檢驗呢?

首先差分把所有長度比mid大的鏈上除了lca之外的所有點權+1。dfs求出每個點的點權,順便記下有多少點是被所有路徑經過的。對於這些點,如果有乙個點使得它到他的父親那條邊被刪掉後,長度最長的路徑都能卡過mid,那麼返回true.

那麼檢查所有點發現長度最長的路徑卡不過mid,那麼返回false。

然後這題搞完了。

#include#include

#include

#include

#include

using

namespace

std;

intn,m;

inline

intread()

while

(isdigit(ch))

return num*f;

}struct

edgeedge[

1000010

];int head[1000100

],num;

inline

void add(int

from,int to,int

dis);

head[

from]=num;

}struct

node

}q[300020

];int s[400020][20],d[400020][20

];int deep[400020

];int vis[300020],e[300020

];int pos[1001001

],tot;

intmax,ans;

void find(int x,int

fa)}

void dfs(int x,int fa,int

size)

if(e[x]==size) pos[++tot]=x;

}bool check(int

limit)

dfs(

1,1,size);

for(int i=1;i<=tot;++i)

if(q[1].dis-d[pos[i]][0]<=limit) return1;

return0;

}int

main()

for(int i=1;i<=m;++i) q[i]=(node);

find(

1,1);

for(int j=1;j<20;++j)

for(int i=1;i<=n;++i)

for(int i=1;i<=m;++i)

if(from==to)

for(int j=19;j>=0;--j)

dis+=d[from][0]+d[to][0

]; lca=s[from][0

]; max=max(max,dis);

}sort(q+1,q+m+1

);

int l=0,r=max;

while(l<=r)

else l=mid+1

; }

printf("%d

",ans);

return0;

}

luogu P2680 運輸計畫

傳送門 要最長鏈的長度最短,一秒想到二分,因為如果對於某個長度滿足改掉一邊的邊權後能使得所有鏈長度不超過該長度,則所有比他長的長度也滿足.二分最終答案.我們要使得原來長度大於二分的 mid 的鏈刪邊後小於 mid 所以要找出一條最長的,被所有長度大於 mid 的鏈包含的邊,使得最長鏈長度減去這條邊長...

P2680 運輸計畫

好久沒更新部落格了,更一篇吧 qwq 傳送門要求我們讓路徑的最大時間最小 這很二分答案 可以二分答案 mid 然後想辦法 o n 去檢查答案是否合法 可以記錄出路徑長度大於 mid 的路徑,盡量在這些路徑的交集部分建造黑洞 顯而易見 我們可以用邊差分 diff i 來記錄這條邊被幾個大於 mid 的...

P2680 運輸計畫

公元 2044 年,人類進入了宇宙紀元。l 國有 n 個星球,還有 n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1 條航道連通了 l 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物 流飛船需要從 ui 號星球沿最快的宇航路徑飛行到 vi 號星球...