社区讨论
萌新初学虚树1ms,样例过但AC on #9#10,WA on other,求条
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mm2uqz71
- 此快照首次捕获于
- 2026/02/26 10:36 2 周前
- 此快照最后确认于
- 2026/02/27 15:25 2 周前
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 250005;
int n,m,k,tot,a[2 * N],dfn[N],dp[N],dep[N],fa[N][21],mv[N][21];
bool vis[N];
vector<pair<int,int> > g[N],vt[N];
void dfs(int x,int f){
dfn[x] = ++tot;
fa[x][0] = f;
dep[x] = dep[f] + 1;
for (int i = 1; 1 << i <= dep[x]; i++){
fa[x][i] = fa[fa[x][i - 1]][i - 1];
mv[x][i] = min(mv[x][i - 1],mv[fa[x][i - 1]][i - 1]);
}
for (int i = 0; i < g[x].size(); i++){
int nxt = g[x][i].first,num = g[x][i].second;
if (nxt != f){
mv[nxt][0] = num;
dfs(nxt,x);
}
}
}
int get_lca(int x,int y){
if (dep[x] < dep[y]) swap(x,y);
for (int i = 20; i >= 0; i--) if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
if (x == y) return x;
for (int i = 20; i >= 0; i--) if (fa[x][i] != fa[y][i]){
x = fa[x][i];
y = fa[y][i];
}
return fa[x][0];
}
int get_min(int x,int y){
if (dep[x] < dep[y]) swap(x,y);
int res = 1e18;
for (int i = 20; i >= 0; i--) if (dep[fa[x][i]] >= dep[y]){
res = min(res,mv[x][i]);
x = fa[x][i];
}
return res;
}
bool cmp(int x,int y){return dfn[x] < dfn[y];}
void build(int len,int a[]){
sort(a + 1,a + len + 1,cmp);
for (int i = 2; i <= len; i++) a[len + i - 1] = get_lca(a[i - 1],a[i]);
sort(a + 1,a + len * 2,cmp);
len = unique(a + 1,a + len * 2) - a;
for (int i = 1; i < len; i++) vt[a[i]].clear();
for (int i = 2; i < len; i++){
int f = get_lca(a[i - 1],a[i]);
vt[f].push_back({a[i],get_min(f,a[i])});
}
}
void DP(int x){
dp[x] = 0;
for (int i = 0; i < vt[x].size(); i++){
int nxt = vt[x][i].first,num = vt[x][i].second;
DP(nxt);
dp[x] += (vis[nxt] ? num : min(num,dp[nxt]));
}
}
signed main(){
cin >> n;
for (int i = 1,u,v,w; i < n; i++){
cin >> u >> v >> w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
dfs(1,0);
a[1] = 1;
for (cin >> m; m--; ){
cin >> k;
for (int i = 2; i <= k + 1; i++){
cin >> a[i];
vis[a[i]] = 1;
}
build(k + 1,a);
DP(1);
cout << dp[1] << '\n';
for (int i = 2; i <= k + 1; i++) vis[a[i]] = 0;
}
return 0;
}
没有用栈建虚树,用的 dfs 序。
回复
共 4 条回复,欢迎继续交流。
正在加载回复...