CF516D Drazil and Morning Exercise
https://www.luogu.com.cn/problem/CF516D
注意到
min
f
x
\min f_x
minfx的一定是在直径上
以这个点为根,可以得到一个
f
f
f随深度递增的树
直接树上差分,找最大的即可
code:
#include<bits/stdc++.h>
#define N 400050
#define ll long long
using namespace std;
struct edge {
int v, c, nxt;
} e[N << 1];
int p[N], eid;
void init() {
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v, int c) {
e[eid].v = v;
e[eid].c = c;
e[eid].nxt = p[u];
p[u] = eid ++;
}
ll d[N], dd[N], dis[N], sta[N];
int top, stb[N], s[N], q, n;
void dfs(int u, int fa) {
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v, c = e[i].c;
if(v == fa) continue;
//printf(" %d %d %d\n", u, v, c);
d[v] = d[u] + c; dfs(v, u);
}
}
void dfss(int u, int fa) {
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v, c = e[i].c;
if(v == fa) continue;
dd[v] = dd[u] + c; dfss(v, u);
}
}
void dfs1(int u, int fa, ll x) {
s[u] ++, sta[++ top] = dis[u], stb[top] = u;
int pos = lower_bound(sta + 1, sta + 1 + top, dis[u] - x) - sta - 1;
s[stb[pos]] --;
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v, c = e[i].c;
if(v == fa) continue;
dfs1(v, u, x); s[u] += s[v];
}
top --;
}
int main() {
init();
scanf("%d", &n);
for(int i = 1; i < n; i ++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
insert(u, v, c), insert(v, u, c);
}
int S = 1, T = 1;
d[S] = 0; dfs(S, S);
for(int i = 1; i <= n; i ++) if(d[S] < d[i]) S = i;
//for(int i = 1; i <= n; i ++) printf("%lld ", d[i]); printf(" %d\n", S);
d[S] = 0; dfs(S, S);
for(int i = 1; i <= n; i ++) if(d[T] < d[i]) T = i;
// for(int i = 1; i <= n; i ++) printf("%lld ", d[i]); printf(" %d\n", T);
dd[T] = 0; dfss(T, T);
for(int i = 1; i <= n; i ++) dis[i] = max(d[i], dd[i]);
int rt = 1;
for(int i = 1; i <= n; i ++) if(dis[i] < dis[rt]) rt = i;
// printf("\n");
// for(int i = 1; i <= n; i ++) printf("%lld ", dis[i]); printf(" %d\n", rt);
sta[++ top] = 0; stb[top] = 0;
scanf("%d", &q);
while(q --) {
ll x;
scanf("%lld", &x);
dfs1(rt, rt, x);
int ans = 0;
for(int i = 1; i <= n; i ++) ans = max(ans, s[i]), s[i] = 0;
printf("%d\n", ans);
}
return 0;
}