#include <cstdio>
#include <vector>
using namespace std;
class UnionFindSets {
int *father, *rank;
public:
UnionFindSets(int N) {
father = new int[N], rank = new int[N];
for(int x=0; x<N; x++) father[x] = x, rank[x] = 1;
}
int FindSets(int x) {
if(x != father[x]) father[x] = FindSets(father[x]);
return father[x];
}
bool SameSets(int x, int y) {
return FindSets(x) == FindSets(y);
}
void UnionSets(int x, int y) {
if((x = FindSets(x)) == (y = FindSets(y))) return;
if(rank[x] <= rank[y]) father[x] = y, rank[y] += rank[x];
else father[y] = x, rank[x] += rank[y];
}
~UnionFindSets() {
delete[] father, delete[] rank;
}
};
struct Edge { int v, t; Edge *next; };
struct Path { int v; Path *next; };
struct Node { int v, t, depth, key, path; };
struct Pair { int a, b, lca, t; };
class Tarjan : public UnionFindSets {
bool *visited;
int *ancestor;
Edge **edge;
Path **path;
void lca(int x, int top, Node g[], Pair *&q) {
for(Edge *e=edge[x]; e; e=e->next) {
if(e->v==top) continue;
g[e->v] = (Node){x, g[x].t+e->t, g[x].depth+1, 0, 0};
lca(e->v, x, g, q);
UnionSets(x, e->v);
ancestor[FindSets(e->v)] = x;
}
visited[x] = true;
for(Path *p=path[x]; p; p=p->next) {
if(!visited[p->v]) continue;
*q++ = (Pair){x, p->v, ancestor[FindSets(p->v)], 0};
}
}
public:
Tarjan(int N, Edge *e[], Path *p[]) : UnionFindSets(N) {
visited = new bool[N], ancestor = new int[N];
for(int x=0; x<N; x++)
visited[x] = false, ancestor[x] = x, e[x] = NULL, p[x] = NULL;
edge = e, path = p;
}
void LCA(Node g[], Pair q[]) {
g[0] = (Node){0, 0, 0, 0, 0};
lca(0, -1, g, q);
}
~Tarjan() {
delete[] visited, delete[] ancestor;
}
};
void read_data(int n, Node g[], int m, Pair q[]) {
Edge *edge[n], _edge[2][n-1];
Path *path[n], _path[2][m];
Tarjan tarjan(n, edge, path);
for(int i=0; i<n-1; i++) {
int a, b, t;
scanf("%d%d%d", &a, &b, &t); a--, b--;
_edge[0][i] = (Edge){b, t, edge[a]}, edge[a] = _edge[0]+i;
if(a==b) continue;
_edge[1][i] = (Edge){a, t, edge[b]}, edge[b] = _edge[1]+i;
}
for(int i=0; i<m; i++) {
int u, v;
scanf("%d%d", &u, &v); u--, v--;
_path[0][i] = (Path){v, path[u]}, path[u] = _path[0]+i;
if(u==v) continue;
_path[1][i] = (Path){u, path[v]}, path[v] = _path[1]+i;
}
tarjan.LCA(g, q);
}
void xpush(Node g[], vector<Pair> &x, Pair p) {
if(p.a==p.b) return;
int i = g[p.a].path;
if(i) {
if(x[i].t<p.t) swap(x[i], p);
if(g[x[i].b].depth<=g[p.b].depth) return;
xpush(g, x, (Pair){x[i].b, p.b, p.b, p.t});
}
else {
g[p.a].path = x.size();
x.push_back(p);
}
}
void xstep(Node g[], vector<Pair> &x, int i) {
int a = x[i].a, b = x[i].b;
while(a!=b) {
g[a].key = max(g[a].key, x[i].t), a = g[a].v;
if(g[a].path) {
x[i].b = a, xpush(g, x, (Pair){a, b, b, x[i].t});
break;
}
}
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
Node g[n];
Pair q[m];
read_data(n, g, m, q);
int maxlen = -1, zero = 0;
for(int i=0; i<m; i++) {
q[i].t = g[q[i].a].t+g[q[i].b].t-2*g[q[i].lca].t;
if(maxlen<q[i].t) maxlen = q[i].t, zero = i;
}
swap(q[0], q[zero]);
int a = q[0].a, b = q[0].b, key = 1;
while(a!=b) {
if(g[a].depth<g[b].depth) swap(a, b), key = 3-key;
g[a].key = key, a = g[a].v;
}
g[a].key = 3;
int minlen = 0;
for(int i=1; i<m; i++) {
if(g[q[i].lca].key) {
for(int &a=q[i].a; !g[a].key; a=g[a].v);
for(int &b=q[i].b; !g[b].key; b=g[b].v);
}
if(g[q[i].lca].key==0 || q[i].a==q[i].b) {
minlen = max(minlen, q[i].t);
q[i--] = q[--m];
}
}
vector<Pair> x;
Pair p0 = q[0];
if(g[p0.a].depth<g[p0.b].depth) swap(p0.a, p0.b);
x.push_back(p0);
for(int i=1; i<m; i++) {
Pair pi = q[i];
if(g[pi.a].depth<g[pi.b].depth) swap(pi.a, pi.b);
if(p0.lca==pi.lca)
if(g[p0.a].key==g[pi.a].key) {
xpush(g, x, (Pair){p0.a, pi.a, pi.a, pi.t});
xpush(g, x, (Pair){p0.b, pi.b, pi.b, pi.t});
}
else {
xpush(g, x, (Pair){p0.b, pi.a, pi.a, pi.t});
xpush(g, x, (Pair){p0.a, pi.b, pi.b, pi.t});
}
else {
if(g[p0.a].key==g[pi.a].key) {
xpush(g, x, (Pair){p0.a, pi.a, pi.a, pi.t});
xpush(g, x, (Pair){p0.b, p0.lca, p0.lca, pi.t});
}
else {
xpush(g, x, (Pair){p0.b, pi.a, pi.a, pi.t});
xpush(g, x, (Pair){p0.a, p0.lca, p0.lca, pi.t});
}
xpush(g, x, (Pair){pi.b, p0.lca, p0.lca, pi.t});
}
}
a = x[0].a, b = x[0].b;
while(a!=b) {
if(g[a].depth<g[b].depth) swap(a, b);
g[a].key = x[0].t-g[a].t+g[g[a].v].t, a = g[a].v;
}
a = x[0].a, b = x[0].b;
while(a!=b) {
if(g[a].depth<g[b].depth) swap(a, b);
if(g[a].path) xstep(g, x, g[a].path);
maxlen = min(maxlen, g[a].key), a = g[a].v;
}
printf("%d\n", max(minlen, maxlen));
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。