【题意分析】
首先明确一个性质,要删除的边肯定在最长路径上面,因为如果不在上面的话最大值相当于没变。
然后我们二分这个最大值能不能达到,check的过程:
找到所有比二分值长的路径,设其数量为tot,运用树上差分:路径两段差分值+1,lca处差分值-2(因为是边权题,如果是点权,则是在lca父亲处-1)
然后我们充分利用差分数组:从根到点的路径上的差分值之和就是这些路径(比二分值大的路径)有多少经过了这条边,如果一条边被tot条路径经过(就是所有比二分值大的路径),那么就可以删掉这条边试试,取一下最大值
Code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 400000
using namespace std;
struct fls {int to, next, val;} edge[MAXN << 1];
struct Node {int x, y, lca, val;} data[MAXN];
int head[MAXN << 1], top[MAXN], son[MAXN], father[MAXN], size[MAXN], delta[MAXN];
int depth[MAXN], pre[MAXN], lgst, n, m, cnt, maxlen, tot, maxedge;
inline int read () {
register int s = 0, w = 1;
register char ch = getchar ();
while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
return s * w;
}
inline void connect (int u, int v, int w) {
edge[++cnt].to = v, edge[cnt].val = w, edge[cnt].next = head[u], head[u] = cnt;
}
inline int LCA (int x, int y) {
while (top[x] != top[y]) {
if (depth[top[x]] < depth[top[y]]) swap (x, y);
x = father[top[x]];
}
return depth[x] > depth[y] ? y : x;
}
void DFS1 (int now, int fa, int d) {
depth[now] = d, father[now] = fa, size[now] = 1; int maxson = -1;
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to; if (v == fa) continue;
pre[v] = pre[now] + edge[i].val;
DFS1 (v, now, d + 1), size[now] += size[v];
if (size[v] > maxson) maxson = size[v], son[now] = v;
}
}
void DFS2 (int now, int top_heavy) {
top[now] = top_heavy; if (! son[now]) return;
DFS2 (son[now], top_heavy);
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to;
if (v != son[now] && v != father[now]) DFS2 (v, v);
}
}
void DFS3 (int now, int val) {
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to; if (v == father[now]) continue;
DFS3 (v, edge[i].val), delta[now] += delta[v];
}
if (delta[now] == tot) lgst = max (lgst, val);
}
inline bool check (int x) {
memset (delta, 0, sizeof delta); lgst = tot = 0;
for (register int i = 1; i <= m; i++)
if (data[i].val > x) {
delta[data[i].x]++, delta[data[i].y]++,
delta[data[i].lca] -= 2, tot++;
}
DFS3 (1, 0); return maxlen - lgst <= x;
}
int main () {
n = read (), m = read ();
for (register int i = 1; i < n; i++) {
int u = read (), v = read (), w = read ();
connect (u, v, w), connect (v, u, w);
maxedge = max (maxedge, w);
}
DFS1 (1, 0, 1), DFS2 (1, 1);
for (register int i = 1; i <= m; i++) {
data[i].x = read (), data[i].y = read ();
data[i].lca = LCA (data[i].x, data[i].y);
data[i].val = pre[data[i].x] + pre[data[i].y] - pre[data[i].lca] * 2;
maxlen = max (maxlen, data[i].val);
}
int L = maxlen - maxedge, R = maxlen, ans;
while (L <= R) {
int mid = L + R >> 1;
if (check (mid)) ans = mid, R = mid - 1;
else L = mid + 1;
}
return printf ("%d\n", ans), 0;
}