我要去死,,,,
虚树模板提,,真是够了我自己写的模板没错,,,第一次我是用的多次memset,所以T了,,,第二次,,学会了不用memset直接dp时清零结果有些节点没有覆盖所以有T了,,tm的分数还一样于是我就以为我的模板有问题就可劲差错可劲查错,是我dp写残了,,,我去死吧!!!
知识点:1.虚树 2.不要每次都用memset那一定会T,,而且注意细节,学会每次完成时顺便清零 3.错误有可能就在你想不到的地方,,,
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#define N 250000
using namespace std;
typedef long long LL;
struct edge{ int point,nxt,v,w;};
edge e1[(N<<2)+5],e2[(N<<2)+5];
LL f[N+5];
int x,a[N+5],fa[N+5][22],deep[N+5],cnt1,cnt2,top,st[N+5],dfn[N+5],n,mini[N+5];
bool used[N+5],exist[N+5];
void addedge1(int u1,int v1,int w1){
e1[++cnt1].nxt = e1[u1].point; e1[u1].point = cnt1; e1[cnt1].v = v1; e1[cnt1].w =w1; }
void insert1(int u1,int v1,int w1){ addedge1(u1,v1,w1); addedge1(v1,u1,w1);}
void addedge2(int u1,int v1,int w1){
e2[++cnt2].nxt = e2[u1].point; e2[u1].point = cnt2; e2[cnt2].v = v1; e2[cnt2].w =w1; }
void insert2(int u1,int v1,int w1){ addedge2(u1,v1,w1); addedge2(v1,u1,w1);}
bool cmp(int a,int b){ return dfn[a]<dfn[b];}
int getnum(){
char c; int num;
while (!isdigit(c=getchar()));
num = c - '0';
while (isdigit( c= getchar())) num = 10*num + c -'0';
return num;
}
void dfs(int x){
dfn[x] = ++top;
for (int i = 1; i <= 20; ++i)
fa[x][i] = fa[fa[x][i-1]][i-1];
// c[x][i] = c[x][i-1];
// if (fa[x][i-1]!=0) c[x][i] = min(c[x][i],c[fa[x][i-1]][i-1]);}
for (int p = e1[x].point; p; p = e1[p].nxt)
if (!dfn[e1[p].v]){
deep[e1[p].v] = deep[x]+1; fa[e1[p].v][0] = x; mini[e1[p].v] = min(mini[x],e1[p].w);
dfs(e1[p].v);
}
}
void init(){
cnt1 = 0; top = 0; mini[1] = 0x7fffffff;
n = getnum();
memset(e1,0,sizeof(e1));
for (int i = 1; i < n; ++i) {
int u1=getnum(),v1=getnum(),w1=getnum();
insert1(u1,v1,w1);}
//cout<<e1[1].point<<endl<<e1[6].nxt<<endl;
//for (int p = e1[1].point;p;p=e1[p].nxt) cout<<e1[p].v<<endl;
dfs(1);
//for (int i = 1; i<=n;++i) cout<<dfn[i]<<endl;
}
int LCA(int u,int v){
if (deep[u] < deep[v]) swap(u,v);
int l = deep[u] - deep[v];
for (int i = 0; i <= 20; ++i)
if (l&(1<<i)) u = fa[u][i];
for (int i = 20 ; i >=0; --i)
if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
if (u!=v) return fa[u][0];
return u;
}
void make_it(){
x = getnum(); top = 0;
cnt2 = 0;
for (int i = 1; i <=x;++i) a[i] = getnum();
st[0] = 1;
sort(a+1,a+x+1,cmp);
for (int i = 1; i <=x; ++i) exist[a[i]] = 1;
for (int i = 1; i <= x; ++i){
int lca = LCA(a[i],st[top]);
while ((top)&&(deep[lca] < deep[st[top]])){
if (deep[st[top-1]]<=deep[lca])
{insert2(st[top],lca,mini[st[top]]); --top; break;}
insert2(st[top-1],st[top],mini[st[top]]);
top--;
}
if (st[top] != lca) st[++top] = lca;
if (st[top] != a[i]) st[++top] = a[i];
}
while (top) { insert2(st[top-1],st[top],mini[st[top]]); top--;}
}
void dp(int x){
f[x] = 0;
for (int p = e2[x].point; p ;p = e2[p].nxt)
if (deep[e2[p].v]>deep[x]) {
dp(e2[p].v);
if (exist[e2[p].v]) f[x] += e2[p].w;
else f[x] += min((LL)e2[p].w,f[e2[p].v]);}
e2[x].point = 0;
}
void DO_IT(){
int m;
m = getnum();
while (m--){
make_it();
dp(1);
for (int i = 1; i<=x;++i) exist[a[i]] = 0;
printf("%lld\n",f[1]);
}
}
int main(){
init();
DO_IT();
return 0;
}