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
| #include <cstdio> #include <algorithm> #include <cctype> #include <cstring> #include <vector> using namespace std; typedef long long int64; inline int read(int f = 1, int x = 0, char ch = ' ') { while(!isdigit(ch = getchar())) if(ch == '-') f = -1; while(isdigit(ch)) x = x*10+ch-'0', ch = getchar(); return f*x; } const int N = 5e5+5; struct Edge { int next, to, w; Edge(int next = 0, int to = 0, int w = 0):next(next), to(to), w(w) {}; }edge[N<<1]; int head[N], tot; void _add(int x, int y, int z) { edge[++tot] = Edge(head[x], y, z); head[x] = tot; } void add(int x, int y, int z) { _add(x, y, z); _add(y, x, z); } int n, m, q, ac[20][N], d[N], nfd[N], dfn[N], t, p[N]; int64 f[N]; void dfs(int x, int fa) { ac[0][x] = fa; dfn[++t] = x; nfd[x] = t; d[x] = d[fa]+1; for(int i = 1; i < 20; ++i) ac[i][x] = ac[i-1][ac[i-1][x]]; for(int i = head[x]; i; i = edge[i].next) { int y = edge[i].to, z = edge[i].w; if(y == fa) continue; f[y] = min(f[x], 1ll*z); dfs(y, x); } } int LCA(int x, int y) { if(d[x] > d[y]) swap(x, y); for(int i = 19; ~i; --i) if(d[ac[i][y]] >= d[x]) y = ac[i][y]; if(x == y) return x; for(int i = 19; ~i; --i) if(ac[i][x] != ac[i][y]) x = ac[i][x], y = ac[i][y]; return ac[0][x]; } bool cmp(int x, int y) { return nfd[x] < nfd[y]; } namespace vtree { int s[N], top, cov[N]; vector<int> edge[N]; void add(int x, int y) { edge[x].push_back(y); } void insert(int x) { int lca = LCA(x, s[top]); if(lca == s[top]) return void(s[++top] = x); while(top > 1&&nfd[s[top-1]] >= nfd[lca]) add(s[top-1], s[top]), --top; if(s[top] != lca) add(lca, s[top]), s[top] = lca; s[++top] = x; } void build() { s[top = 1] = 1; for(int k = 1; k <= m; ++k) cov[p[k]] = 1, insert(p[k]); while(top > 1) add(s[top-1], s[top]), --top; } int64 dp(int x) { int64 ret = 0; for(int i = 0; i < edge[x].size(); ++i) ret += dp(edge[x][i]); edge[x].clear(); if(!cov[x]) return min(ret, f[x]); cov[x] = 0; return f[x]; } } int main() { n = read(); for(int i = 1; i < n; ++i) { int x = read(), y = read(), z = read(); add(x, y, z); } q = read(); memset(f, 0x3f, sizeof(f)); dfs(1, 0); while(q--) { m = read(); for(int k = 1; k <= m; ++k) p[k] = read(); sort(p+1, p+1+m, cmp); vtree::build(); printf("%lld\n", vtree::dp(1)); } return 0; }
|