HDU 4313 Matrix
/*
dp[i][0]代表的是在当前以i节点为根节点的子树中,i所在的连通块中没有危险节点的最小花费;
dp[i][1]代表的是在当前以i节点为根节点的子树中,i所在的连通块中有一个危险节点的最小花费;
注意:是i所在的连通块允许出现一个危险节点
如果i是叶子节点:如果i为危险点dp[i][0] = inf,dp[i][1]= 0;否则dp[i][0] = dp[i][1] = 0;(好理解)
如果i不是叶子节点:如果i是危险点dp[i][0] = inf , dp[i][1] = sum( min(dp[son][0],dp[son][1]+w));
否则dp[i][0] = sum( min(dp[son][0],dp[son][1]+w)),
dp[i][1] = min(dp[i][0] – min(dp[son][0],dp[son][1]+w)+dp[son][1])。
如果子节点是存在一个危险节点的,那么就要比较是在dp[i][0]的基础上修复现在的路好,还是以前截断的路好
如 dp[i][0]-dp[son][0]+dp[son][1]是修复以前截断的路
dp[i][0]-dp[son][1]-w+dp[son][1]=dp[i][0]+w;
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define inf 1000000000000000
struct node{
int son;
long long w;
};
vector<node>tree[100005];
long long dp[100005][2],w;
int t,n,k,x,y;
bool vis[100005];
void dfs(int now,int pre){
if(tree[now].size()==1&&pre!=-1){///如果是叶子节点
if(vis[now]) dp[now][0]=inf;
}
///不是叶子节点
else{
for(int i=0;i<tree[now].size();i++){
if(tree[now][i].son==pre) continue;//不能往上回溯
dfs(tree[now][i].son,now);
}
if(vis[now]){
dp[now][0]=inf;
for(int i=0;i<tree[now].size();i++){
if(tree[now][i].son==pre) continue;//不能往上回溯
dp[now][1] += min(dp[tree[now][i].son][0],tree[now][i].w+dp[tree[now][i].son][1]);
}
}
else{
dp[now][1]=inf;
for(int i=0;i<tree[now].size();i++){
if(tree[now][i].son==pre) continue;//不能往上回溯
dp[now][0] += min(dp[tree[now][i].son][0],tree[now][i].w+dp[tree[now][i].son][1]);
}
for(int i=0;i<tree[now].size();i++){
if(tree[now][i].son==pre) continue;//不能往上回溯
dp[now][1] = min(dp[now][1],dp[now][0]-min(dp[tree[now][i].son][0],tree[now][i].w+dp[tree[now][i].son][1])+dp[tree[now][i].son][1]);
}
}
//printf("%d %lld %lld\n",now,dp[now][1],dp[now][0]);
}
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&k);
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
for(int i=1;i<n;i++){
scanf("%d%d%lld",&x,&y,&w);
node tem;
tem.son=y,tem.w=w;
tree[x].push_back(tem);
tem.son=x;
tree[y].push_back(tem);
}
for(int i=1;i<=k;i++){
scanf("%d",&x);
vis[x]=1;
}
dfs(0,-1);
printf("%lld\n",min(dp[0][0],dp[0][1]));
for(int i=0;i<n;i++)
tree[i].clear();
}
return 0;
}
/*
1
5 3
2 1 8
1 0 5
2 4 5
1 3 4
2
4
0
10
*/