社区讨论
AC on #2,#3,#7 求调
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mm7s9ylt
- 此快照首次捕获于
- 2026/03/01 21:26 上周
- 此快照最后确认于
- 2026/03/04 19:30 5 天前
rt, record,
CPP#include <algorithm>
#include <iostream>
#include <stack>
#define int long long
using namespace std;
const int N = 2.5e5 + 5;
const int inf = 1e18;
int n, m, k;
int sc[N];
bool isSource[N];
struct Graph {
struct Edge {
int u, v, w, next;
void clear() {
u = v = w = next = 0;
}
void output() {
printf("Path %d %d %d %d\n", u, v, w, next);
}
} e[N * 2];
int head[N], cur = 0;
void add(int u, int v, int w) {
e[++cur] = Edge{u, v, w, head[u]};
head[u] = cur;
}
void Tree(int root, int fa, int dep) {
for(int i = 1; i <= dep; i++) printf(" ");
printf("%d\n", root);
for(int i = head[root]; i; i = e[i].next) {
if(e[i].v == fa) continue;
Tree(e[i].v, root, dep + 1);
}
}
} O, T;
int Log[N], Fa[N][30];
int dep[N], dfn[N], fa[N], path[N], DFN = 0;
void dfs1(int u, int f, int de) {
fa[u] = f; Fa[u][0] = f; dep[u] = de; dfn[u] = ++DFN;
for(int i = O.head[u]; i; i = O.e[i].next) {
int v = O.e[i].v;
if(v == f) continue;
path[v] = min(path[u], O.e[i].w);
dfs1(v, u, de + 1);
}
}
int st[N], top = 0;
int lowbit(int x) {
return x & (-x);
}
int LCA(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
for(int ddep = dep[u] - dep[v]; ddep; ddep -= lowbit(ddep))
u = Fa[u][Log[lowbit(ddep)]];
if(u == v) return u;
for(int i = Log[n]; i >= 0; i--) {
if(Fa[u][i] == Fa[v][i]) continue;
u = Fa[u][i], v = Fa[v][i];
}
return fa[u];
}
bool cmp(int u, int v) {
return dfn[u] < dfn[v];
}
int dfs2(int u, int f) {
int res = 0;
for(int i = T.head[u]; i; i = T.e[i].next) {
res += dfs2(T.e[i].v, u);
}
if(isSource[u]) res = path[u];
else res = min(path[u], res);
isSource[u] = 0;
T.head[u] = 0;
return res;
}
void Solve() {
T.cur = 0;
scanf("%lld", &k);
for(int i = 1; i <= k; i++) {
scanf("%lld", &sc[i]);
isSource[sc[i]] = 1;
}
sort(sc + 1, sc + k + 1, cmp);
top = 0;
st[0] = 0; st[++top] = sc[1];
for(int i = 2; i <= k; i++) {
int now = sc[i];
int lca = LCA(now, st[top]);
while(1) {
if(lca == st[top]) {
break;
} else if(dep[st[top]] > dep[lca] && dep[lca] > dep[st[top - 1]]) {
T.add(lca, st[top], 1);
st[top] = lca;
break;
} else if(lca == st[top - 1]) {
T.add(lca, st[top], 1);
top--;
break;
} else {
T.add(st[top - 1], st[top--], 1);
}
}
st[++top] = now;
}
int root = st[1];
for(int i = 1; i < top; i++) {
T.add(st[i], st[i + 1], 1);
st[i] = 0;
}
printf("%lld\n", dfs2(root, 0));
}
signed main() {
scanf("%lld", &n);
for(int i = 1; i < n; i++) {
int u, v, w;
scanf("%lld%lld%lld", &u, &v, &w);
O.add(u, v, w);
O.add(v, u, w);
}
path[1] = inf;
dfs1(1, 0, 1);
Log[1] = 0;
for(int i = 2; i <= n; i++) Log[i] = Log[i / 2] + 1;
for(int i = 1; i <= Log[n]; i++)
for(int j = 1; j <= n; j++)
Fa[j][i] = Fa[Fa[j][i - 1]][i - 1];
scanf("%lld", &m);
while(m--) Solve();
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...