萌新刚学虚树,用的 二次排序+LCA 建树,在第 5 6 7 9 TLE
#include <bits/stdc++.h>
using namespace std;
using ubt = long long;
inline int read() {
int s = 0, w = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') w = -w;
c = getchar();
}
while (isdigit(c)) {
s = s * 10 + c - 48;
c = getchar();
}
return s * w;
}
#define end_ putchar('\n')
#define spc_ putchar(' ')
void write(ubt x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + 48);
}
const int maxN = 2.5e5 + 7;
int n;
int head[maxN], tot;
struct edge {
int ls, to, w;
} e[maxN << 1];
void add(int u, int v, int w) {
e[++tot] = {head[u], v, w};
head[u] = tot;
}
int dfn[maxN], cnt;
int get(int x, int y) {
return dfn[x] < dfn[y] ? x : y;
}
int g[30][maxN];
int a[maxN];
int fa[maxN];
void dfs(int x, int f) {
fa[x] = f;
dfn[x] = ++cnt;
g[0][dfn[x]] = f;
for (int i = head[x]; i; i = e[i].ls) {
int to = e[i].to;
if (to == f) continue;
a[to] = e[i].w;
dfs(to, x);
}
}
int lca(int x, int y) {
if (x == y) return x;
x = dfn[x], y = dfn[y];
if (x > y) swap(x, y);
x++;
int t = __lg(y - x + 1);
return get(g[t][x], g[t][y - (1 << t) + 1]);
}
int m;
struct ques {
int k;
vector<int> qu;
} q[maxN << 1];
int G[maxN << 1], Gg[maxN << 1], len;
vector<int> E[maxN];
bool is[maxN];
void change(int x, int H) {
a[H] = min(a[H], a[x]);
if (fa[x] && !is[fa[x]])
change(fa[x], H);
}
ubt dp[maxN];
void calc(int x, int f) {
dp[x] = 0;
for (auto to : E[x]) {
if (to == f) continue;
calc(to, x);
if (is[to])
dp[x] += a[to];
else
dp[x] += min(dp[to], 1ll * a[to]);
}
}
int main() {
n = read();
for (int i = 1; i < n; i++) {
int x = read(), y = read(), z = read();
add(x, y, z);
add(y, x, z);
}
dfs(1, 0);
for (int t = 1; t <= 20; t++)
for (int i = 1; i + (1 << t) - 1 <= n; i++)
g[t][i] = get(g[t - 1][i], g[t - 1][i + (1 << (t - 1))]);
m = read();
for (int i = 1; i <= m; i++) {
q[i].k = read();
for (int j = 1; j <= q[i].k; j++) {
int o = read();
q[i].qu.push_back(o);
G[++G[0]] = o;
}
}
/*
16
1 2 1
2 3 1
2 4 1
4 5 1
4 6 1
1 7 1
7 8 1
7 9 1
7 10 1
8 11 1
11 12 1
11 13 1
13 14 1
14 15 1
14 16 1
1
7 3 4 5 6 7 12 14
*/
// cerr << "G : ";
// for (int i = 1; i <= G[0]; i++)
// cerr << G[i] << ' ';
// cerr << '\n';
auto cmp = [](int a, int b) {
return dfn[a] < dfn[b];
};
sort(G + 1, G + G[0] + 1, cmp);
G[0] = unique(G + 1, G + G[0] + 1) - G - 1;
Gg[++len] = 1;
for (int i = 1; i < G[0]; i++) {
Gg[++len] = G[i];
Gg[++len] = lca(G[i], G[i + 1]);
}
Gg[++len] = G[G[0]];
sort(Gg + 1, Gg + len + 1, cmp);
len = unique(Gg + 1, Gg + len + 1) - Gg - 1;
for (int i = 1; i < len; i++) {
int lc = lca(Gg[i], Gg[i + 1]);
is[lc] = is[Gg[i + 1]] = true;
E[lc].push_back(Gg[i + 1]);
}
// for (int i = 1; i <= n; i++) {
// cerr << i << " : ";
// for (int j : E[i])
// cerr << j << ' ';
// cerr << '\n';
// }
for (int i = 1; i <= n; i++)
if (is[i])
change(i, i);
for (int i = 1; i <= n; i++)
is[i] = false;
for (int i = 1; i <= m; i++) {
for (auto j : q[i].qu)
is[j] = true;
calc(1, 0);
write(dp[1]), end_;
for (auto j : q[i].qu)
is[j] = false;
}
}