#include <bits/stdc++.h>
#define int long long
#define N 250010
using namespace std;
int n, m, k, u, v, w, cnt, val[N], head[N];
int ss[N << 1], sta[N << 1], deep[N], ff[N][22], done[N];
struct edge {
    int nxt, to, w;
}e[N << 1];
void add_edge (int from, int to, int val) {
    e[++cnt].nxt = head[from];
    e[cnt].to = to;
    e[cnt].w = val;
    head[from] = cnt;
}
int dfn[N], low[N], _dfn = 0;
void pre (int u, int fa) {
    dfn[u] = ++_dfn;
    deep[u] = deep[fa] + 1;
    ff[u][0] = fa;
    for (int i = 1; (1 << i) <= deep[u]; ++i) {
        ff[u][i] = ff[ff[u][i - 1]][i - 1];
    }
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (v != fa) {
            val[v] = min (val[u], e[i].w);
            pre (v, u);
            //  printf ("val[%lld] = min (%lld, %lld)\n", v, val[u], e[i].w);
        }
    }
    low[u] = _dfn;
}
bool cmp (const int &lhs, const int &rhs) {
    return dfn[lhs] < dfn[rhs];
}
int lca (int u, int v) {
    //  printf ("lca (%lld, %lld) = ", u, v);
    if (deep[u] < deep[v]) swap (u, v);
    for (int i = 20; i >= 0; --i) {
        if (deep[ff[u][i]] >= deep[v]) {
            u = ff[u][i];
        }
    }
    if (u == v) return u;
    for (int i = 20; i >= 0; --i) {
        if (ff[u][i] != ff[v][i]) {
            u = ff[u][i];
            v = ff[v][i];
        }
    }
    //printf ("%lld\n", ff[u][0]);
    return ff[u][0];
}
int get_ans (int u, int fa) {
    if (done [u]) return val[u];
    int res = 0;
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (v != fa) {
            res += get_ans (v, u);
        }
    }
    return min (res, val[u]);
}
signed main () {
    //freopen ("2495.in", "r", stdin);
    scanf ("%lld", &n);
    for (int i = 1; i < n; ++i) {
        scanf ("%lld %lld %lld", &u, &v, &w);
        add_edge (u, v, w);
        add_edge (v, u, w);
    }
    memset (val, 0x3f, sizeof (val));
    pre (1, 0);
    /*
    for (int i = 1; i <= n; ++i) {
        printf ("node = %lld, val = %lld, low = %lld, dfn = %lld\n", i, val[i], low[i], dfn[i]);
    } */
    memset (head, 0, sizeof (head));
    scanf ("%lld", &m);
    for (int i = 1; i <= m; ++i) {
        //  printf ("ask = %lld\n", i);
        scanf ("%lld", &k);
        for (int j = 1; j <= k; ++j) {
            scanf ("%lld", &ss[j]);
            done[ss[j]] = true;
        }
        sort (ss + 1, ss + 1 + k, cmp);
        for (int j = k; j > 1; --j) {
            ss[++k] = lca (ss[j], ss[j - 1]);
        }
        ss[++k] = 1;
        sort (ss + 1, ss + 1 + k, cmp);
        k = unique (ss + 1, ss + 1 + k) - ss - 1;
        int top = 0; cnt = 0;
        for (int j = 1; j <= k; ++j) {
            while (top && low[sta[top]] < dfn[ss[j]]) --top;
            add_edge (sta[top], ss[j], val[j]);
            add_edge (ss[j], sta[top], val[j]);
            sta[++top] = ss[j];
        }
        get_ans (1, 0);
        //print_tree (1, 0);
        printf ("%lld\n", get_ans (1, 0));
        
        for (int j = 1; j <= k; ++j) {
            //printf ("dp[%lld] = %lld\n", ss[j], dp[ss[j]]);
            done[ss[j]] = false, head[ss[j]] = 0;
        }
        
    }
}
原文:https://www.cnblogs.com/maomao9173/p/10359469.html