社区讨论
10pts 求条
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mix8m9yt
- 此快照首次捕获于
- 2025/12/08 22:19 3 个月前
- 此快照最后确认于
- 2025/12/09 16:44 3 个月前
RT
CPP#include <bits/stdc++.h>
using namespace std;
#define FILE(x) freopen(x".in", "r", stdin);freopen(x".out", "w", stdout);
int n, q, m, a[500001];
bool imp[250001];
long long value[250001], dp[250001];
int fa[250001], depth[250001], son[250001], sz[250001], head[250001], dfn[250001], ddfn[250001], tot;
vector <pair <int, long long> > e[250001];
vector <int> g[250001];
int hi[500001];
long long mi[19], ST[250001][19];
void dfs1(int x, int father, int dep){
fa[x] = father;
depth[x] = dep;
sz[x] = 1;
for (pair <int, long long> u : e[x]){
if (u.first == father){
continue;
}
value[u.first] = u.second;
dfs1(u.first, x, dep + 1);
sz[x] += sz[u.first];
if (sz[u.first] > sz[son[x]]){
son[x] = u.first;
}
}
return;
}
void dfs2(int x, int he){
dfn[x] = ++tot;
ddfn[tot] = x;
head[x] = he;
if (son[x]){
dfs2(son[x], he);
for (pair <int, long long> u : e[x]){
if (u.first == fa[x] || u.first == son[x]){
continue;
}
dfs2(u.first, u.first);
}
}
return;
}
int lca(int u, int v){
while (head[u] != head[v]){
if (depth[head[u]] < depth[head[v]]){
swap(u, v);
}
u = fa[head[u]];
}
if (depth[u] > depth[v]){
swap(u, v);
}
return u;
}
long long qmin(int l, int r){
return min(ST[l][hi[r - l + 1]], ST[r - (1 << hi[r - l + 1]) + 1][hi[r - l + 1]]);
}
long long querymin(int u, int v){
long long res = 1e18;
while (head[u] != head[v]){
if (depth[head[u]] < depth[head[v]]){
swap(u, v);
}
res = min(res, qmin(dfn[head[u]], dfn[u]));
u = fa[head[u]];
}
if (u == v){
return res;
}
if (depth[u] > depth[v]){
swap(u, v);
}
res = min(res, qmin(dfn[u] + 1, dfn[v]));
return res;
}
bool cmp(int x, int y){
return dfn[x] < dfn[y];
}
void buildVT(){
for (int i = 1; i <= n; i++){
while (!g[i].empty()){
g[i].pop_back();
}
}
sort(a + 1, a + m + 1, cmp);
int tmp = m;
for (int i = 2; i <= tmp; i++){
a[++m] = lca(a[i - 1], a[i]);
}
a[++m] = 1;
sort(a + 1, a + m + 1, cmp);
m = unique(a + 1, a + m + 1) - a - 1;
for (int i = 2; i <= m; i++){
g[lca(a[i - 1], a[i])].push_back(a[i]);
}
return;
}
void calc(int x){
dp[x] = 0;
for (int u : g[x]){
calc(u);
if (imp[u]){
dp[x] += querymin(x, u);
} else {
dp[x] += min(dp[u], querymin(x, u));
}
}
return;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int u, v;
long long w;
cin >> n;
for (int i = 1; i < n; i++){
cin >> u >> v >> w;
e[u].push_back({v, w});
e[v].push_back({u, w});
}
dfs1(1, 0, 1);
dfs2(1, 1);
mi[0] = 1;
hi[1] = 0;
for (int i = 1; i <= 18; i++){
mi[i] = mi[i - 1] << 1;
for (int j = mi[i - 1] + 1; j <= mi[i]; j++){
hi[j] = i;
}
}
for (int i = 1; i <= n; i++){
ST[i][0] = value[ddfn[i]];
}
for (int j = 1; j <= 18; j++){
for (int i = 1; i <= n; i++){
ST[i][j] = min(ST[i][j - 1], ST[i + mi[j - 1]][j - 1]);
}
}
cin >> q;
while (q--){
cin >> m;
for (int i = 1; i <= m; i++){
cin >> a[i];
imp[a[i]] = true;
}
buildVT();
calc(1);
cout << dp[1] << "\n";
for (int i = 1; i <= m; i++){
imp[a[i]] = false;
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...