【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 250005 #define INF 1e9 #define INFP 1e18 #define MAXLOG 20 struct edge {int dest, len;}; vector <edge> a[MAXN], b[MAXN]; int n, m, timer; long long cost[MAXN]; bool mark[MAXN], valued[MAXN]; int dfn[MAXN], depth[MAXN], q[MAXN]; int father[MAXN][MAXLOG], minv[MAXN][MAXLOG]; bool cmp(int x, int y) { return dfn[x] < dfn[y]; } void dfs(int pos, int fa, int len) { dfn[pos] = ++timer; depth[pos] = depth[fa] + 1; father[pos][0] = fa; minv[pos][0] = len; for (int i = 1; i < MAXLOG; i++) { father[pos][i] = father[father[pos][i - 1]][i - 1]; minv[pos][i] = min(minv[pos][i - 1], minv[father[pos][i - 1]][i - 1]); } for (unsigned i = 0; i < a[pos].size(); i++) if (a[pos][i].dest != fa) dfs(a[pos][i].dest, pos, a[pos][i].len); } int Lca(int x, int y) { if (depth[x] < depth[y]) swap(x, y); for (int i = MAXLOG - 1; i >= 0; i--) if (depth[father[x][i]] >= depth[y]) x = father[x][i]; if (x == y) return x; for (int i = MAXLOG - 1; i >= 0; i--) if (father[x][i] != father[y][i]) { x = father[x][i]; y = father[y][i]; } return father[x][0]; } void insert(int x, int y) { int pos = y, minnum = INF; for (int i = MAXLOG - 1; i >= 0; i--) if (depth[father[pos][i]] >= depth[x]) { minnum = min(minnum, minv[pos][i]); pos = father[pos][i]; } b[x].push_back((edge){y, minnum}); } long long get(int pos, long long len) { if (mark[pos]) return len; long long ans = 0; for (unsigned i = 0; i < b[pos].size(); i++) ans += get(b[pos][i].dest, b[pos][i].len); return min(ans, len); } int main() { scanf("%d", &n); for (int i = 1; i < n; i++) { int x, y, value; scanf("%d%d%d", &x, &y, &value); a[x].push_back((edge){y, value}); a[y].push_back((edge){x, value}); } for (int j = 0; j < MAXLOG; j++) minv[0][j] = INF; dfs(1, 0, INF); int T; scanf("%d", &T); while (T--) { scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d", &q[i]); mark[q[i]] = true; } sort(q + 1, q + m + 1, cmp); static int Stack[MAXN], used[MAXN]; int top = 1, cnt = 0; Stack[1] = 1; for (int i = 1; i <= m; i++) { int lca = Lca(q[i], Stack[top]); if (lca == Stack[top]) Stack[++top] = q[i]; else { while (dfn[lca] < dfn[Stack[top - 1]]) { insert(Stack[top - 1], Stack[top]); used[++cnt] = Stack[top--]; } if (dfn[lca] == dfn[Stack[top - 1]]) { insert(Stack[top - 1], Stack[top]); used[++cnt] = Stack[top--]; Stack[++top] = q[i]; } else { insert(lca, Stack[top]); used[++cnt] = Stack[top--]; Stack[++top] = lca; Stack[++top] = q[i]; } } } while (top >= 2) { insert(Stack[top - 1], Stack[top]); used[++cnt] = Stack[top--]; } used[++cnt] = Stack[top--]; for (int i = 1; i <= cnt; i++) cost[used[i]] = 0; printf("%lld\n", get(1, INFP)); for (int i = 1; i <= cnt; i++) b[used[i]].clear(); for (int i = 1; i <= m; i++) mark[q[i]] = false; } return 0; }