f[x]=SUM{ min(f[y], z) } ( y是不重要的点)
建立虚树,然后dp
#include <bits/stdc++.h>
using namespace std ;
const int N=3e6,M=N,inf=1e9;
#define int long long
int mn[N],n;
int stk[N],top ;
int nxt[M],go[M],w[M],hd[N],all;
int f[N];
vector<int> VT[N];
void add_(int x,int y,int z){
go[++all]=y,w[all]=z,nxt[all]=hd[x],hd[x]=all;
}
void V_ADD(int x,int y){
VT[x].push_back(y);
VT[y].push_back(x);
}
int dep[N],F[N][21];
int dfn[N],pool ,B[N] ;
int m,a[N] ;
int cmp(int i,int j){
return dfn[i]<dfn[j] ;
}
void init(int x,int fa){
int i,y;
dfn[x]=++pool;
dep[x]=dep[fa]+1;
F[x][0]=fa;
for(i=0;i<=19;i++) F[x][i+1]=F[F[x][i]][i];
for(i=hd[x];i;i=nxt[i]){
y=go[i]; if(y==fa) continue;
mn[y]=min(mn[x],w[i]);
init(y,x);
}
}
int lca(int x,int y){
int i;
if(dep[x]<dep[y]) swap(x,y);
for(i=19;i>=0;i--){
if(dep[F[x][i]]>=dep[y]) x=F[x][i];
}
if(x==y) return x;
for(i=19;i>=0;i--){
if(F[x][i]!=F[y][i]) x=F[x][i],y=F[y][i];
}
return F[x][0];
}
void dp(int x,int fa) {
f[x] = 0;
for(int i = 0;i < VT[x].size();i++) {
int v = VT[x][i],w = mn[v];
if(v == fa) continue;
dp(v,x);
if(B[v]) {
f[x] += w;
} else {
f[x] += min(f[v],w);
}
}
VT[x].clear();
}
void build() {
sort(a + 1,a + 1 + m,cmp);
top = 1;
stk[top] = 1;
for(int i = 1;i <= m;i++) {
if(a[i] != 1) {
int l = lca(a[i],stk[top]);
if(l != stk[top]) {
while(top >= 2 && dfn[l] < dfn[stk[top - 1]]) {
V_ADD(stk[top - 1],stk[top]);
top--;
}
if(dfn[l] > dfn[stk[top - 1]]) {
V_ADD(l,stk[top]);
stk[top] = l;
} else {
V_ADD(l,stk[top]);
top--;
}
}
stk[++top] = a[i];
}
}
for(int i = 1;i < top;i++) {
V_ADD(stk[i],stk[i + 1]);
}
}
signed main(){
int i,x,y,z;
cin>>n;
for(i=1;i<n;i++)
cin>>x>>y>>z,add_(x,y,z),add_(y,x,z);
memset(mn,127,sizeof mn);
init(1,0);
int tes;
cin>>tes;
while(tes--){
cin>>m;
for(i=1;i<=m;i++){
cin>>a[i]; B[a[i]]=1;
}
build();
dp(1,0);
cout<<f[1]<<'\n';
for(i=1;i<=m;i++) B[a[i]]=0;
}
}
浙公网安备 33010602011771号