1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <iostream> #include <cstdio> #include <cctype> #include <cstring> #define maxn 300010 #define gc getchar using namespace std;
int read() { int x = 0; char c = gc(); while (!isdigit(c)) c = gc(); while (isdigit(c)) x = x * 10 + c - '0', c = gc(); return x; }
int n, m;
struct Edge { int to, next, w; } e[maxn * 2]; int c1, head[maxn]; inline void add_edge(int u, int v, int w) { e[c1].to = v; e[c1].w = w; e[c1].next = head[u]; head[u] = c1++; }
struct Query { int u, v, lca; } Q[maxn];
int f[maxn][21], dis[maxn], dep[maxn], _w[maxn]; void dfs(int u, int fa) { for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to, w = e[i].w; if (v == fa) continue; dis[v] = dis[u] + w; f[v][0] = u; dep[v] = dep[u] + 1; _w[v] = w; dfs(v, u); } }
void init_lca() { for (int j = 1; j <= 20; ++j) for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1]; }
inline int get_lca(int x, int y) { if (dep[x] < dep[y]) swap(x, y); for (int i = 20; ~i; --i) if (dep[f[x][i]] >= dep[y]) x = f[x][i]; if (x == y) return x; for (int i = 20; ~i; --i) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; return f[x][0]; }
int Dis[maxn], Max, tot; void Dfs(int u, int fa) { for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; Dfs(v, u); Dis[u] += Dis[v]; } if (Dis[u] == tot) Max = max(Max, _w[u]); }
bool check(int x) { memset(Dis, 0, sizeof Dis); int Mx = 0; tot = Max = 0; for (int i = 1; i <= m; ++i) { int u = Q[i].u, v = Q[i].v, lca = Q[i].lca; if (dis[u] + dis[v] - 2 * dis[lca] <= x) continue; Mx = max(Mx, dis[u] + dis[v] - 2 * dis[lca]); ++Dis[u]; ++Dis[v]; Dis[lca] -= 2; ++tot; } Dfs(1, 0); return Mx - Max <= x; }
int main() { memset(head, -1, sizeof head); n = read(); m = read(); for (int i = 1; i < n; ++i) { int x = read(), y = read(), z = read(); add_edge(x, y, z); add_edge(y, x, z); } for (int i = 1; i <= m; ++i) Q[i].u = read(), Q[i].v = read(); dep[1] = 1; dfs(1, 0); init_lca(); int Max = 0; for (int i = 1; i <= m; ++i) { int u = Q[i].u, v = Q[i].v, lca; lca = Q[i].lca = get_lca(u, v); Max = max(Max, dis[u] + dis[v] - 2 * dis[lca]);
} int l = 0, r = Max, mid, ans; while (l <= r) { mid = l + r >> 1; if (check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } cout << ans << endl; return 0; }
|