P2495 [SDOI2011] 消耗战 的代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5*1e5;
const int maxm=20;
const int inf=LLONG_MAX;
struct Edge{int u,v,w,nxt;};
struct Graph{;
Edge e[maxn+5];
int hd[maxn+5],et;
inline void Init(){
et=0;
memset(hd,-1,sizeof(hd));
memset(e,-1,sizeof(e));
}
inline void Adde(int u,int v,int w){
e[et].u=u,e[et].v=v,e[et].w=w,e[et].nxt=hd[u],hd[u]=et++;
}
};
int n,m,K;
Graph A,B;
int fa[maxn+5][maxm+5];
int dis[maxn+5][maxm+5];
int dfn[maxn+5],tt;
int de[maxn+5];
int p[maxn+5];
bool ip[maxn+5];
int f[maxn+5];
void DfsA(int u,int F){
int v,w;
dfn[u]=++tt;
for(int i=A.hd[u];~i;i=A.e[i].nxt){
v=A.e[i].v,w=A.e[i].w;
if(v==F) continue;
fa[v][0]=u;
dis[v][0]=w;
de[v]=de[u]+1;
DfsA(v,u);
}
}
inline void Init(){
for(int j=1;j<=maxm;j++){
for(int i=1;i<=n;i++){
fa[i][j]=fa[fa[i][j-1]][j-1];
dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]);
}
}
}
inline int Lca(int x,int y){
if(de[x]<de[y]) swap(x,y);
for(int j=maxm;j>=0;j--)
if(de[fa[x][j]]>=de[y])
x=fa[x][j];
if(x==y) return x;
for(int j=maxm;j>=0;j--)
if(fa[x][j]!=fa[y][j])
x=fa[x][j],y=fa[y][j];
return fa[x][0];
}
inline int Dis(int x,int y){
int res=inf;
if(de[x]<de[y]) swap(x,y);
for(int j=maxm;j>=0;j--){
if(de[fa[x][j]]>=de[y]){
res=min(res,dis[x][j]);
x=fa[x][j];
}
}
return res;
}
void DfsB(int u,int F,int V){
int v,w,sum=0;
if(ip[u]){
f[u]=V;
return;
}
for(int i=B.hd[u];~i;i=B.e[i].nxt){
v=B.e[i].v,w=B.e[i].w;
DfsB(v,u,w);
sum+=f[v];
}
f[u]=min(V,sum);
}
inline bool Cmp(int x,int y){return dfn[x]<dfn[y];}
signed main(){
int u,v,w;
A.Init(),B.Init();
scanf("%lld",&n);
for(int i=1;i<n;i++){
scanf("%lld%lld%lld",&u,&v,&w);
A.Adde(u,v,w),A.Adde(v,u,w);
}
de[1]=1;
DfsA(1,0);
Init();
scanf("%lld",&m);
while(m--){
scanf("%lld",&K);
for(int i=1;i<=K;i++){
scanf("%lld",&p[i]);
ip[p[i]]=1;
}
p[++K]=1;
sort(p+1,p+K+1,Cmp);
w=K;
for(int i=1;i<w;i++)
p[++K]=Lca(p[i],p[i+1]);
sort(p+1,p+K+1,Cmp);
K=unique(p+1,p+K+1)-p-1;
for(int i=1;i<K;i++){
u=Lca(p[i],p[i+1]);
v=p[i+1];
w=Dis(u,v);
B.Adde(u,v,w);
}
DfsB(1,0,inf);
printf("%lld\n",f[1]);
B.et=0;
for(int i=1;i<=K;i++){
ip[p[i]]=0;
B.hd[p[i]]=-1;
}
}
return 0;
}