【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 1000005 #define MAXLOG 20 #define INF 1e9 vector <int> a[MAXN], b[MAXN]; bool mark[MAXN]; long long sum[MAXN], cnt[MAXN], ans; int maxnum[MAXN], minnum[MAXN], ansmax, ansmin; int timer, dfn[MAXN], depth[MAXN], father[MAXN][MAXLOG]; void work(int pos, int fa) { if (mark[pos]) { sum[pos] = 0; cnt[pos] = 0; maxnum[pos] = 0; minnum[pos] = 0; int tmp; int Max = 0, Nax = -1; int Min = 0, Nin = INF; for (unsigned i = 0; i < b[pos].size(); i++) { if (b[pos][i] == fa) continue; work(b[pos][i], pos); int len = depth[b[pos][i]] - depth[pos]; ans += sum[pos] * cnt[b[pos][i]] + (sum[b[pos][i]] + cnt[b[pos][i]] * len) * cnt[pos]; sum[pos] += sum[b[pos][i]] + cnt[b[pos][i]] * len; cnt[pos] += cnt[b[pos][i]]; maxnum[pos] = max(maxnum[pos], maxnum[b[pos][i]] + len); tmp = maxnum[b[pos][i]] + len; if (tmp > Max) { Nax = Max; Max = tmp; } else Nax = max(Nax, tmp); minnum[pos] = min(minnum[pos], minnum[b[pos][i]] + len); tmp = minnum[b[pos][i]] + len; if (tmp < Min) { Nin = Min; Min = tmp; } else Nin = min(Nin, tmp); } ans += sum[pos]; cnt[pos]++; if (Nax != -1) ansmax = max(ansmax, Max + Nax); if (Nin != INF) ansmin = min(ansmin, Min + Nin); } else { sum[pos] = 0; cnt[pos] = 0; maxnum[pos] = 0; minnum[pos] = INF; int tmp; int Max = -1, Nax = -1; int Min = INF, Nin = INF; for (unsigned i = 0; i < b[pos].size(); i++) { if (b[pos][i] == fa) continue; work(b[pos][i], pos); int len = depth[b[pos][i]] - depth[pos]; ans += sum[pos] * cnt[b[pos][i]] + (sum[b[pos][i]] + cnt[b[pos][i]] * len) * cnt[pos]; sum[pos] += sum[b[pos][i]] + cnt[b[pos][i]] * len; cnt[pos] += cnt[b[pos][i]]; maxnum[pos] = max(maxnum[pos], maxnum[b[pos][i]] + len); tmp = maxnum[b[pos][i]] + len; if (tmp > Max) { Nax = Max; Max = tmp; } else Nax = max(Nax, tmp); minnum[pos] = min(minnum[pos], minnum[b[pos][i]] + len); tmp = minnum[b[pos][i]] + len; if (tmp < Min) { Nin = Min; Min = tmp; } else Nin = min(Nin, tmp); } if (Nax != -1) ansmax = max(ansmax, Max + Nax); if (Nin != INF) ansmin = min(ansmin, Min + Nin); } } 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 init(int pos, int fa, int dep) { depth[pos] = dep; father[pos][0] = fa; dfn[pos] = ++timer; for (int i = 1; i < MAXLOG; i++) father[pos][i] = father[father[pos][i - 1]][i - 1]; for (unsigned i = 0; i < a[pos].size(); i++) if (a[pos][i] != fa) init(a[pos][i], pos, dep + 1); } bool cmp(int x, int y) { return dfn[x] < dfn[y]; } int main() { int n; scanf("%d", &n); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); a[x].push_back(y); a[y].push_back(x); } init(1, 0, 1); int T; scanf("%d", &T); while (T--) { int m; scanf("%d", &m); static int q[MAXN]; for (int i = 1; i <= m; i++) { scanf("%d", &q[i]); mark[q[i]] = true; } static int used[MAXN], Stack[MAXN]; int cnt = 1, s = 1, top = 1; sort(q + 1, q + m + 1, cmp); Stack[1] = 1; used[1] = 1; if (q[1] == 1) s++; for (int i = s; i <= m; i++) { int Lca = lca(q[i], Stack[top]); if (Lca == Stack[top]) { Stack[++top] = q[i]; continue; } while (dfn[Lca] < dfn[Stack[top - 1]]) { b[Stack[top]].push_back(Stack[top - 1]); b[Stack[top - 1]].push_back(Stack[top]); used[++cnt] = Stack[top--]; } if (dfn[Lca] == dfn[Stack[top - 1]]) { b[Stack[top]].push_back(Stack[top - 1]); b[Stack[top - 1]].push_back(Stack[top]); used[++cnt] = Stack[top--]; Stack[++top] = q[i]; } else { b[Stack[top]].push_back(Lca); b[Lca].push_back(Stack[top]); used[++cnt] = Stack[top--]; Stack[++top] = Lca; Stack[++top] = q[i]; } } while (top >= 2) { b[Stack[top]].push_back(Stack[top - 1]); b[Stack[top - 1]].push_back(Stack[top]); used[++cnt] = Stack[top--]; } ans = 0; ansmax = 0; ansmin = INF; work(1, 0); printf("%lld %d %d\n", ans, ansmin, ansmax); for (int i = 1; i <= m; i++) mark[q[i]] = false; for (int i = 1; i <= cnt; i++) b[used[i]].clear(); } return 0; }