社区讨论
样例不过玄关求条
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mm2ucd0s
- 此快照首次捕获于
- 2026/02/26 10:25 2 周前
- 此快照最后确认于
- 2026/02/27 15:15 2 周前
rt,马蜂优良
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e6 + 1;
int n, cnt, top[MAXN], dfn[MAXN], siz[MAXN], fa[MAXN], seg[MAXN], son[MAXN], dep[MAXN], a[MAXN], len, me[MAXN], k[MAXN], q, m;
struct edge {
int y, w;
};
vector<edge> c[MAXN], vt[MAXN];
void dfs1(int x, int last) {
dep[x] = dep[last] + 1;
fa[x] = last;
siz[x] = 1;
for(int i = 0; i < c[x].size(); i++) {
int y = c[x][i].y;
if(y == last) {
continue;
}
dfs1(y, x);
me[y] = min(me[x], c[x][i].w);
if(siz[y] > siz[son[x]]) {
son[x] = y;
}
}
}
void dfs2(int x, int tp) {
dfn[x] = ++cnt;
seg[cnt] = x;
top[x] = tp;
if(son[x]) {
dfs2(son[x], tp);
}
for(int i = 0; i < c[x].size(); i++) {
int y = c[x][i].y;
if(y == fa[x] || y == son[x]) {
continue;
}
dfs2(y, y);
}
}
int LCA(int x, int y) {
while(top[x] != top[y]) {
if(dep[top[x]] > dep[top[y]]) {
x = fa[top[x]];
}
else {
y = fa[top[y]];
}
}
return (dep[x] > dep[y] ? y : x);
}
bool cmp(int x, int y) {
return dfn[x] < dfn[y];
}
void link(int x, int y) {
vt[x].push_back({y, 0});
}
void bvt() {
sort(k + 1, k + m + 1, cmp);
for(int i = 1; i < m; i++) {
a[++len] = k[i];
a[++len] = LCA(k[i], k[i + 1]);
}
a[++len] = k[m];
sort(a + 1, a + len + 1, cmp);
len = unique(a + 1, a + len + 1) - a - 1;
for(int i = 2; i <= len; i++) {
link(LCA(a[i], a[i - 1]), a[i]);
}
}
int dfsdp(int x) {
if(vt[x].size() == 0) {
return me[x];
}
int res = 0;
for(int i = 0; i < vt[x].size(); i++) {
int y = vt[x][i].y;
res += dfsdp(y);
}
vt[x].clear();
return min(res, me[x]);
}
signed main() {
cin >> n;
for(int i = 1, x, y, w; i < n; i++) {
cin >> x >> y >> w;
c[x].push_back({y, w});
c[y].push_back({x, w});
}
dfs1(1, 0);
dfs2(1, 1);
cin >> q;
while(q--) {
me[1] = 1e18;
len = 0;
cin >> m;
for(int i = 1; i <= m; i++) {
cin >> k[i];
}
bvt();
cout << dfsdp(1, -1) << "\n";
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...