#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;
}

一͛世͛珍͛藏͛
86 声望6 粉丝

« 上一篇
大数加法
下一篇 »
amiaodaifu.com