虚树

https://www.lydsy.com/JudgeOnline/problem.php?id=2286

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=250001;
typedef long long LL;
typedef unsigned long long ULL;
//typedef pair<LL,LL> P;
const LL mod=1e9+7;
using namespace std;
struct node{
    int to,nxt,val;
}g[2*maxn];
int head[maxn],cnt,tot,top,dfn[maxn],deep[maxn],f[maxn][20],q[maxn],sta[maxn];
vector<int> gg[maxn];
LL mx[maxn];
void add(int u,int v,int w){
    g[cnt].to=v;
    g[cnt].val=w;
    g[cnt].nxt=head[u];
    head[u]=cnt++;
}
bool cmp(int x,int y){
    return dfn[x]<dfn[y];
}
void dfs(int x,int fa){
    //cout<<x<<' '<<mx[x]<<endl;
    int t=head[x];
    dfn[x]=tot++;
    deep[x]=deep[fa]+1;
    f[x][0]=fa;
    while(t!=-1){
        if(g[t].to!=fa){
            if(x!=1)
                mx[g[t].to]=min((LL)g[t].val,mx[x]);
            else
                mx[g[t].to]=g[t].val;
            dfs(g[t].to,x);
        }
        t=g[t].nxt;
    }
}
int LCA(int x,int y){
    if(deep[x]<deep[y]){
        swap(x,y);
    }
    while(deep[x]>deep[y]){
        for(int j=15;j>=0;j--){
            if(deep[f[x][j]]>=deep[y]){
                x=f[x][j];
            }
        }
    }
    if(x==y) return x;
    while(f[x][0]!=f[y][0]){
        for(int j=15;j>=0;j--){
            if(f[x][j]!=f[y][j]){
                x=f[x][j];
                y=f[y][j];
            }
        }
    }
    return f[x][0];
}
void Insert(int x) {
    if(top==1){
        sta[++top]=x;
        return;
    }
    int lca=LCA(x,sta[top]);
    if(lca==sta[top]) return ;
    while(top>1&&dfn[sta[top-1]]>=dfn[lca]) {
        gg[sta[top-1]].push_back(sta[top]);
        top--;
    }
    if(lca!=sta[top]) {
        gg[lca].push_back(sta[top]);
        sta[top]=lca;
    }
    sta[++top]=x;
}
LL solve(int x){
    //cout<<x<<endl;
    if(gg[x].size() == 0) return mx[x];
    LL sum=0;
    for(int i=0;i<gg[x].size();i++){
        sum+=solve(gg[x][i]);
        //cout<<x<<' '<<sum<<endl;
    }
    gg[x].clear();
    return min(sum,(LL)mx[x]);
}
int main(){
    int n;
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    int x,y,w;
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&x,&y,&w);
        add(x,y,w);
        add(y,x,w);
    }
    dfs(1,0);
    mx[1]=1ll<<(60);
    for(int j=1;j<=15;j++){
        for(int i=1;i<=n;i++){
            f[i][j]=f[f[i][j-1]][j-1];
        }
    }
    int m,k;
    scanf("%d",&m);
    while(m--){
        scanf("%d",&k);
        for(int i=1;i<=k;i++){
            scanf("%d",&q[i]);
        }
        sort(q+1,q+1+k,cmp);
        sta[top=1]=1;
        for(int i=1;i<=k;i++){
            Insert(q[i]);
        }
        while(top>0){
            gg[sta[top-1]].push_back(sta[top]);
            top--;
        }
        printf("%lld
",solve(1));
    }
}
/*

*/
原文地址:https://www.cnblogs.com/Profish/p/10900607.html