社区讨论
50pts球跳
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mjbeztuo
- 此快照首次捕获于
- 2025/12/18 20:26 2 个月前
- 此快照最后确认于
- 2025/12/18 20:33 2 个月前
CPP
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 254514
#define int long long
struct sd{
int y,z;
bool operator<(sd p)const{
return z<p.z;
}
};
int n,m;
vector<sd> v[N],g[N];
int fa[N][25],dep[N];
int dfn[N],id;
int mini[N][25];
int gj[N];
int vis[N];
long long dp[2][N];
sd a[N],b[2*N];
void dfs(int x,int f){
fa[x][0]=f;
dep[x]=dep[f]+1;
dfn[x]=++id;
for(int i=0;i<v[x].size();i++){
if(v[x][i].y==f)continue;
dfs(v[x][i].y,x);
mini[v[x][i].y][0]=v[x][i].z;
}
}int lca(int x,int y){
if(dep[x]>dep[y]){
swap(x,y);
}while(dep[x]!=dep[y]){
y=fa[y][signed(log2(dep[y]-dep[x]))];
}int d=log2(dep[x]);
while(d>=0){
if(fa[x][d]!=fa[y][d]){
x=fa[x][d];
y=fa[y][d];
}d--;
}if(x==y){
return x;
}else{
return fa[x][0];
}
}int getmin(int x,int y){
if(dep[x]>dep[y]){
swap(x,y);
}int minx=1e9;
while(x!=y){
int d=log2(dep[y]-dep[x]);
minx=min(minx,mini[y][d]);
y=fa[y][d];
}return minx;
}void check(int x){
if(vis[x]!=id){
g[x].clear();
vis[x]=id;
}
}void DP(int x){
if(gj[x]==id){
dp[0][x]=dp[1][x]=1e9;
return;
}dp[0][x]=dp[1][x]=0;
check(x);
for(int i=0;i<g[x].size();i++){
DP(g[x][i].y);
dp[0][x]+=g[x][i].z;
dp[1][x]+=min(dp[0][g[x][i].y],dp[1][g[x][i].y]);
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int x,y,z;
cin>>x>>y>>z;
v[x].push_back({y,z});
v[y].push_back({x,z});
}dfs(1,1);
for(int j=1;j<=20;j++){
for(int i=1;i<=n;i++){
fa[i][j]=fa[fa[i][j-1]][j-1];
mini[i][j]=min(mini[i][j-1],mini[fa[i][j-1]][j-1]);
}
}cin>>m;
for(id=1;id<=m;id++){
int k;
cin>>k;
k++;
a[1].y=a[1].z=1;
for(int i=2;i<=k;i++){
cin>>a[i].y;
a[i].z=dfn[a[i].y];
gj[a[i].y]=id;
}sort(a+1,a+k+1);
int c=0;
for(int i=1;i<k;i++){
b[++c]=a[i];
int l=lca(a[i].y,a[i+1].y);
b[++c]={l,dfn[l]};
}b[++c]=a[k];
sort(b+1,b+c+1);
int p=0;
for(int i=1;i<=c;i++){
if(b[i].y!=b[i-1].y){
b[++p]=b[i];
}
}c=p;
for(int i=1;i<c;i++){
int l=lca(b[i].y,b[i+1].y);
check(l);
g[l].push_back({b[i+1].y,getmin(l,b[i+1].y)});
}DP(1);
cout<<min(dp[0][1],dp[1][1])<<"\n";
}
return 0;
}
https://www.luogu.com.cn/record/253824157
我不会写假了吧
我不会写假了吧
回复
共 0 条回复,欢迎继续交流。
正在加载回复...