虚树+树形DP乱搞
代码有些丑...
#include<bits/stdc++.h>
using namespace std;
long long n,m,len2=0,pp,trs[2500020],d[2500020],lin2[2500200],q[2500020],p[550020][26],lin[800020],len=0,dfsin[800020],cnt=0,h[800020];
long long w[2500200],f[2500020];
bool f2[5000200];
struct one
{
long long y,next;
long long v;
};
one e[5000020];
bool cmp(long long a,long long b)
{return dfsin[a]<dfsin[b];}
struct newtree
{
long long y,next,v;
};
newtree tree[5000020];
void insert(long long x,long long y,long long v)
{
e[++len].next=lin[x];
lin[x]=len;
e[len].y=y;
e[len].v=v;
}
void insert2(long long x,long long y)
{
tree[++len2].next=lin2[x];
lin2[x]=len2;
tree[len2].y=y;
}
void dfs(long long id,long long v,long long fa)
{
dfsin[id]=++cnt;
for(long long i=lin[id];i;i=e[i].next)
{
if(fa==e[i].y)continue;
d[e[i].y]=d[id]+1;
p[e[i].y][0]=id;
f[e[i].y]=min(v,e[i].v);
dfs(e[i].y,min(v,e[i].v),id);
}
}
void init()
{
for(long long j=1;(1<<j)<=n;j++)
{
for(long long i=1;i<=n;i++)
{
p[i][j]=p[p[i][j-1]][j-1];
}
}
}
long long lca(long long a,long long b)
{
if(d[a]>d[b])swap(a,b);
long long F=d[b]-d[a];
for(long long i=0;(1<<i)<=F;i++)if((1<<i)&F)b=p[b][i];
if(a!=b)
{
for(long long i=log2(n);i>=0;i--)
{
if(p[a][i]!=p[b][i]){a=p[a][i];b=p[b][i];}
}
a=p[a][0];
}
return a;
}
void DP(long long p)
{
if(f2[p])
{
w[p]=f[p];
return;
}
long long ans=0;
for(long long i=lin2[p];i;i=tree[i].next)
{
DP(tree[i].y);
ans+=w[tree[i].y];
}
if(!ans)w[p]=f[p];
else w[p]=min(f[p],ans);
}
int main()
{
//freopen("xf.in","r",stdin);
//freopen("xf.out","w",stdout);
scanf("%lld",&n);
f[0]=999999999999;
long long x,y,v;
insert(0,1,999999999999);
insert(1,0,999999999999);
for(long long i=1;i<n;i++)
{
scanf("%lld%lld%lld",&x,&y,&v);
insert(x,y,v);insert(y,x,v);
}
dfs(0,999999999999,0);
init();
scanf("%lld",&m);
for(long long i=1;i<=m;i++)
{
scanf("%lld",&pp);
for(long long i=1;i<=pp;i++)
{
scanf("%lld",&h[i]);
}
sort(h+1,h+pp+1,cmp);
long long sz=0;
trs[sz++]=0;
long long tail=0;
for(long long i=1;i<=pp;i++)
{
//记得要初始化
long long LCA=lca(trs[sz-1],h[i]);
if(LCA==trs[sz-1])trs[sz++]=h[i];
else
{
while(sz>=2&&d[trs[sz-2]]>=d[LCA])
{
insert2(trs[sz-2],trs[sz-1]);
sz--;
q[++tail]=trs[sz];
}
if(LCA!=trs[sz-1])
{
insert2(LCA,trs[--sz]);
q[++tail]=trs[sz];
trs[sz++]=LCA;
}
trs[sz++]=h[i];
}
}
for(long long i=0;i<sz-1;i++)
{
insert2(trs[i],trs[i+1]);
q[++tail]=trs[i];
}
q[++tail]=trs[sz-1];
for(long long i=1;i<=pp;i++)f2[h[i]]=true;
DP(0);
for(long long i=1;i<=pp;i++)f2[h[i]]=false;
printf("%lld\n",w[0]);
len2=0;
for(long long i=1;i<=tail;i++)
lin2[q[i]]=0;
}
return 0;
}