傳送門
給出乙個有 n
nn 個點的樹,每個點有兩個權值 a
ia_i
ai 和 b
ib_i
bi,現在求一條長度為 m
mm 的路徑(即路徑上的點有 m
mm 個),使得 σai
σb
i\frac
σbiσa
i 最小。如不存在長度為 m
mm 的鏈,輸出 −1-1
−1。注:當 m=−
1m=-1
m=−1
時,路徑長度無限制(但不能為空)。
資料範圍:m≤n
≤2×1
05
m\le n\le2\times10^5
m≤n≤2×
105,ai,
bi≤2
×105
a_i,b_i\le 2\times10^5
ai,bi
≤2×
105。
看到最小化 σai
σb
i\frac
σbiσa
i,不難想到0/1
0/10/
1分數規劃。
假設最後的答案為 λ
\lambda
λ,那對於任意一條長為 m
mm 的路徑,都有 σai
σbi≥
λ\frac≥\lambda
σbiσa
i≥
λ,也即 ∑(a
i−λb
i)≥0
\sum(a_i-\lambda b_i)≥0
∑(ai−
λbi
)≥0,因此將每個點的點權更改為 ai−
λb
ia_i-\lambda b_i
ai−λb
i,然後判斷有沒有一條長度為 m
mm 的路徑權值和為負即可。
對於乙個點的貢獻只有兩種情況,要麼是它直接向下 m
mm 距離的路徑,要麼是以它為 lca
lcalc
a 的兩條鏈拼起來的路徑。
那麼定義 f[x
][i]
f[x][i]
f[x][i
] 為在 x
xx 的子樹中距 x
xx 為 i
ii 的路徑權值最小值,轉移很顯然。
由於 f
ff 的第二維只與深度有關,因此可以用長鏈剖分優化到 o(n
)o(n)
o(n)
。注意到當 m=−
1m=-1
m=−1
時,只選乙個肯定比選多個更優,特判一下就可以了。
#include
#include
#include
#define n 200005
#define eps 1e-3
#define inf 1e18
using
namespace std;
int n,m,t;
int first[n]
,v[n<<1]
,nxt[n<<1]
;int a[n]
,b[n]
,son[n]
,dep[n]
;double ans=inf,val[n]
,*f[n]
,temp[n]
,*pos=temp;
void
add(
int x,
int y)
void
dfs(
int x,
int fa)
dep[x]
=dep[son[x]]+
1;}voiddp(
int x,
int fa)
if(dep[x]
>m) ans=
min(ans,f[x]
[m]-val[fa]);
}bool
check
(double mid)
intmain()
dfs(1,
0);double l=
0,r=
2e5;if(
!check
(r))
return
puts
("-1"),
0;while
(r-l>eps)
printf
("%.2lf"
,l);
return0;
}
洛谷P2652 同花順
所謂同花順,就是指一些撲克牌,它們花色相同,並且數字連續。現在我手裡有n張撲克牌,但它們可能並不能湊成同花順。我現在想知道,最少更換其中的多少張牌,我能讓這 n 張牌都湊成同花順?輸入格式 第一行乙個整數n,表示撲克牌的張數。接下來n行,每行兩個整數 ai 和 bi。其中ai表示第 i 張牌的花色,...
2652 階乘0的數量 V2
題目描述 給出乙個數k,求最小的n,使得n的階乘後面0的數量 k。例如k 1,5的階乘 1 2 3 4 5 120,120後面有1個0。並且4的階乘後面沒有0,所以5是最小的結果。輸入 乙個數k 1 k 10 9 輸出 輸出最小的滿足條件的n。輸入樣例 1輸出樣例 5 又是一道二分答案題。這次直接幹...
2652 階乘0的數量 V2
題目描述 給出乙個數k,求最小的n,使得n的階乘後面0的數量 k。例如k 1,5的階乘 1 2 3 4 5 120,120後面有1個0。並且4的階乘後面沒有0,所以5是最小的結果。輸入 乙個數k 1 k 10 9 輸出 輸出最小的滿足條件的n。輸入樣例 1輸出樣例 5 又是一道二分答案題。這次直接幹...