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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
| #include <cstdio>
#include <algorithm>
int getint() {
int r = 0, k = 1;
char c;
for ( c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') k = -1;
for ( ;'0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
const int maxn = 300005;
int n, m;
struct edge_type {
int to, next, val;
} edge[maxn << 1];
struct plan_type {
int x, y, len;
} plan[maxn];
int h[maxn], cnte = 0;
void ins(int u, int v, int w) {
edge[++cnte].to = v;
edge[cnte].next = h[u];
edge[cnte].val = w;
h[u] = cnte;
}
int fat[maxn], top[maxn], tid[maxn], tmp[maxn], cos[maxn], dep[maxn], dis[maxn], siz[maxn], son[maxn];
void fhe(int x, int father, int depth, int nd) {
dep[x] = depth;
dis[x] = nd;
fat[x] = father;
siz[x] = 1; son[x] = 0;
for (int i = h[x]; i; i = edge[i].next) {
if (edge[i].to == father) continue;
tmp[edge[i].to] = edge[i].val;
fhe(edge[i].to, x, depth + 1, nd + edge[i].val);
siz[x] += siz[edge[i].to];
if (son[x] == 0 || siz[son[x]] < siz[edge[i].to])
son[x] = edge[i].to;
}
}
int dfs_clock = 0;
void che(int x, int tp) {
top[x] = tp; tid[x] = ++dfs_clock; cos[dfs_clock] = tmp[x];
if (son[x]) {
che(son[x], tp);
for (int i = h[x]; i; i = edge[i].next) {
if (edge[i].to == fat[x] || edge[i].to == son[x]) continue;
che(edge[i].to, edge[i].to);
}
}
}
int TTT;
void swap(int &a, int &b) {
TTT = a; a = b; b = TTT;
}
int lca(int a, int b) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]]) swap(a, b);
a = fat[top[a]];
}
if (dep[a] < dep[b]) return a;
return b;
}
bool cmp(plan_type a, plan_type b) {
return a.len < b.len;
}
int q[maxn], cfsz[maxn];
int max(int a, int b) {
return a > b ? a : b;
}
void cf(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
cfsz[tid[top[u]]]++;
cfsz[tid[u]+1]--;
u = fat[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
cfsz[tid[v]+1]++;
cfsz[tid[u]+1]--;
return;
}
int max_plan_len = 0;
bool check(int x) {
int i, j, sz;
for (i = 0; i < m; ++i) if (plan[i].len > x) break;
sz = m - i;
if (q[sz] != 0) return max_plan_len <= x + q[sz];
for (j = 1; j <= n; ++j) cfsz[j] = 0;
for (j = i; j < m; ++j) cf(plan[j].x, plan[j].y);
int T = 0;
for (j = 1; j <= n; ++j) {
T += cfsz[j];
if (T == sz) q[sz] = max(q[sz], cos[j]);
}
return max_plan_len <= x + q[sz];
}
int main () {
n = getint(); m = getint();
int u, v, w;
for (int i = 1; i < n; ++i) {
u = getint(); v = getint(); w = getint();
ins(u, v, w); ins(v, u, w);
}
fhe(1, 0, 0, 0);
che(1, 1);
for (int i = 0; i < m; ++i) {
u = getint(); v = getint();
plan[i].x = u; plan[i].y = v;
plan[i].len = dis[u] + dis[v] - (dis[lca(u, v)] << 1);
max_plan_len = max(plan[i].len, max_plan_len);
}
std::sort(plan, plan + m, cmp);
int l = 0, r = max_plan_len, mid;
while (l < r) {
mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", r);
return 0;
}
|