考虑到删除某个点的最小值就是根到该节点的边的最小值。
然后可以先dfs一遍求出该值,然后考虑对于两个点,删除的价值就是min(dis[x]+dis[y],dis[lca])
所以可以用虚树处理,然后在虚树上dp即可...
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 3e5 + 500,M = 1e6+500;const ll inf = 1e18;
struct Edge { int nxt,to,w; }e1[M],e2[M];
inline void add(int&h,Edge&e,int&tot,int x,int y,int w)
{
if(x == y) return;
e.w = w;
e.to = y;
e.nxt = h;
h = tot;
}
int n,m,k,sz,d[N],p[N][21],deep[N],idx[N];
int h1[N],h2[N],cnt1,cnt2;
ll dis[N],f[N];int s[N],top;
bool _is[N];
const bool cmp(int x,int y) { return idx[x] < idx[y]; }
void dfs(int x)
{
idx[x] = ++sz;
for(register int i = h1[x];i; i = e1[i].nxt)
if(e1[i].to != p[x][0])
{
deep[e1[i].to] = deep[x] + 1;
p[e1[i].to][0] = x;
dis[e1[i].to] = min(dis[x],(ll)e1[i].w);
dfs(e1[i].to);
}
}
inline int get_lca(int x,int y)
{
if(deep[x] < deep[y]) swap(x,y);
repd(i,20,0) if(deep[x] - (1 << i) >= deep[y]) x = p[x][i];
if(x == y) return x;
repd(i,20,0)
if(p[x][i] != p[y][i])
x = p[x][i],y = p[y][i];
return p[x][0];
}
void DFS(int x,int fa)
{
f[x] = 0;ll sum = 0;
for(register int i = h2[x];i;i = e2[i].nxt)
if(e2[i].to != fa){
DFS(e2[i].to,x);
sum += f[e2[i].to];
}
if(_is[x]) f[x] = dis[x];
else f[x] = min(dis[x],sum);
_is[x] = 0;h2[x] = 0;
}
int main()
{
read(n);
rep(i,2,n)
{
int u,v,w;
read(u); read(v); read(w);
add(h1[u],e1[++cnt1],cnt1,u,v,w);
add(h1[v],e1[++cnt1],cnt1,v,u,w);
}
dis[1] = inf;
p[1][0] = 1;
dfs(1);
rep(j,1,20) rep(i,1,n) p[i][j] = p[p[i][j-1]][j-1];
read(m);
rep(qqq,1,m)
{
read(k);
rep(i,1,k) read(d[i]),_is[d[i]] = 1;
cnt2 = 0; s[top = 1] = 1;
sort(d + 1,d + 1 + k,cmp);
rep(i,1,k)
{
int lca = get_lca(s[top],d[i]);
while(top > 1 && deep[s[top - 1]] >= deep[lca])
{
add(h2[s[top - 1]],e2[++cnt2],cnt2,s[top-1],s[top],0);
add(h2[s[top]],e2[++cnt2],cnt2,s[top],s[top-1],0);
top --;
}
add(h2[lca],e2[++cnt2],cnt2,lca,s[top],0);
add(h2[s[top]],e2[++cnt2],cnt2,s[top],lca,0);
s[top] = lca;s[++top] = d[i];
}
rep(i,2,top)
add(h2[s[i - 1]],e2[++cnt2],cnt2,s[i-1],s[i],0),
add(h2[s[i]],e2[++cnt2],cnt2,s[i],s[i-1],0);
DFS(1,1);
printf("%lld\n",f[1]);
}
return 0;
}