Dyd本人 @ 2022-06-05 21:57:44
先发 AC 代码:
#include <bits/stdc++.h>
using LL = long long;
const int N = 3e5 + 100;
const int inf = 0x3f3f3f3f;
const LL INF = 1e18;
int n, num, l, r, mid;
struct Edge{ int ne, ver, w; } e[N << 1];
int h[N], idx = 0;
struct DP
{
LL v; int num;
bool operator < (DP x) const { return v == x.v ? num > x.num : v < x.v; }
DP operator + (DP x){ return {v + x.v, num + x.num}; }
} d[N][3], as, td[3];
LL ans;
void add(int x, int y, int z){ e[idx] = {h[x], y, z}, h[x] = idx++; }
template<typename T>
bool cmx(T &x, T y){ return x < y ? x = y, true : false; }
void dp(int x, int fa)
{
for (int i = h[x], y; ~i; i = e[i].ne) if ((y = e[i].ver) != fa)
{
dp(y, x);
for (int j = 0; j <= 2; ++j) td[j] = {-INF, inf};
for (int j = 0; j <= 2; ++j)
for (int k = 0; k <= 2; ++k) cmx(td[j], d[x][j] + d[y][k]);
cmx(td[1], d[x][0] + d[y][0] + DP{e[i].w - mid, 1});
cmx(td[1], d[x][0] + d[y][1] + DP{e[i].w, 0});
cmx(td[2], d[x][1] + d[y][0] + DP{e[i].w, 0});
cmx(td[2], d[x][1] + d[y][1] + DP{e[i].w + mid, -1});
for (int j = 0; j <= 2; ++j) d[x][j] = td[j];
}
}
int main()
{
scanf("%d %d", &n, &num);
memset(h + 1, -1, n << 2);
for (int i = 1, u, v, w; i < n; ++i)
{
scanf("%d %d %d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
l = -1e12, r = 1e12;
while (l <= r)
{
mid = (l + r) >> 1;
for (int i = 1; i <= n; ++i)
{
d[i][0] = {0, 0};
d[i][1] = {-INF, inf};
d[i][2] = {-mid, 1};
}
dp(1, 0);
as = d[1][0], cmx(as, d[1][1]), cmx(as, d[1][2]);
if (as.num <= num + 1)
{
ans = as.v + LL(mid) * (num + 1);
r = mid - 1;
}
else l = mid + 1;
}
printf("%lld\n", ans);
return 0;
}
第 l = -1e6, r = 1e6
就会 WA 成
所以蒟蒻想问问:为啥
by Alex_Wei @ 2022-06-05 22:15:56
初始值定成斜率最大值和最小值啊
by Alex_Wei @ 2022-06-05 22:17:03
比如说,如果
by Alex_Wei @ 2022-06-05 22:18:24
对于本题而言,因为
by Alex_Wei @ 2022-06-05 22:19:53
比如构造一个点连三条长度为
by Alex_Wei @ 2022-06-05 22:20:47
@Dyd本人 还有这个标题应该写 wqs 二分罢,基础的二分和 wqs 二分差了可不是一点半点。
by Alex_Wei @ 2022-06-05 22:21:40
实际上一般来说
by Dyd本人 @ 2022-06-06 08:39:17
@Alex_Wei 谢谢巨佬,我悟了!