The first time to learn the virtual tree, is to remove irrelevant points. A chain can be maintained in S.
1#include <iostream>2#include <cstring>3#include <cstdio>4#include <algorithm>5 #defineLL Long Long6 using namespacestd;7 ConstLL maxm=501000;8 ConstLL maxn=250100;9 ConstLL inf=1e60;Ten structNode {LL to,next,w;} EDGE[MAXM],EDGE2[MAXM]; One LL HEAD[MAXN],HEAD2[MAXN],DEP[MAXN],H[MAXN],MARK[MAXN],SIZE[MAXN]; A LL TOP[MAXN],FATHER[MAXN],F[MAXN],S[MAXN],MN[MAXN]; - LL cnt1,cnt2,tot,n,u,v,w,tp,m,k; - BOOLVIS[MAXN]; theInlinevoidAdd (LL u,ll v,ll W) -{edge[cnt1].to=v;edge[cnt1].next=head[u];edge[cnt1].w=w;head[u]=cnt1++; -edge[cnt1].to=u;edge[cnt1].next=head[v];edge[cnt1].w=w;head[v]=cnt1++;} -InlinevoidAdd2 (LL u,ll v) +{if(U==V)return; edge2[cnt2].to=v;edge2[cnt2].next=head2[u];head2[u]=cnt2++;} -inline ll Min (ll X,ll y) {returnX>y?y:x;} +InlinevoidGet_int (LL &x) A { atx=0;CharCh=getchar (); LL f=1; - while(ch<'0'|| Ch>'9') {if(ch=='-') f=-1; Ch=GetChar ();} - while(ch>='0'&& ch<='9') {x=x*Ten+ch-'0'; Ch=getchar ();} x*=F; - } -InlinevoidPut_int (LL x) - { in Charch[ -]; LL top=0; - if(x==0) ch[++top]='0'; to while(x) ch[++top]=x%Ten+'0', x/=Ten; + while(top) Putchar (ch[top--]); Putchar ('\ n'); - } the //================================================ * voidDFS1 (LL u) $ {Panax Notoginsengmark[u]=++tot;vis[u]=true; size[u]=1; - for(LL i=head[u];i!=-1; i=edge[i].next) the if(!vis[edge[i].to]) + { Adep[edge[i].to]=dep[u]+1; thefather[edge[i].to]=u; +mn[edge[i].to]=Min (MN[U],EDGE[I].W); - DFS1 (edge[i].to); $size[u]+=size[edge[i].to]; $ } - } - voidDFS2 (LL u,ll chain) the { -Top[u]=chain; vis[u]=true; LL k=0;Wuyi for(inti=head[u];i!=-1; i=edge[i].next) the if(!vis[edge[i].to] && (size[edge[i].to]>size[k) | | k==0)) k=edge[i].to; - if(k==0)return; Wu DFS2 (k,chain); - for(inti=head[u];i!=-1; i=edge[i].next) About if(!vis[edge[i].to] && i!=k) DFS2 (edge[i].to,edge[i].to); $ } - Inline ll Lca (ll U,ll v) - { - while(true) A { + if(Top[u]==top[v])returnDEP[U]>DEP[V]?v:u; the if(Dep[top[u]]>dep[top[v]]) u=Father[top[u]]; - Elsev=Father[top[v]]; $ } the } the //============================================================= theInlineBOOLCMP (LL x,ll y) {returnmark[x]<mark[y];} the voidDp (LL u) - { in thevis[u]=true; F[u]=mn[u]; LL ret=0; the for(inti=head2[u];i!=-1; i=edge2[i].next) About { the Dp (edge2[i].to); theret+=f[edge2[i].to]; the } +head2[u]=-1; - if(ret) f[u]=Min (F[u],ret); the }Bayi voidSolve () the { the Get_int (K); - for(intI=1; i<=k;i++) Get_int (H[i]); -Sort (H +1, h+k+1, CMP); thetp=tot=0; h[++tot]=h[1]; the for(intI=2; i<=k;i++) the if(Lca (H[tot],h[i])!=h[tot]) h[++tot]=H[i]; theCnt2=0; -s[++tp]=1; the for(intI=1; i<=tot;i++) the { theLL u=h[i],f=Lca (U,S[TP]);94 while(true) the { the if(dep[f]>=dep[s[tp-1]]) the {98ADD2 (f,s[tp--]); About if(s[tp]!=f) s[++tp]=F; - Break;101 }102ADD2 (s[tp-1],S[TP]); tp--;103 }104 if(S[tp]!=u) s[++tp]=u; the }106 while(--TP) ADD2 (s[tp],s[tp+1]);107Dp (1);108Put_int (f[1]);109 } the intMain ()111 { the get_int (n);113memset (head,-1,sizeof(head)); cnt1=0; the for(intI=1; i<n;i++) the { the get_int (U), Get_int (v), Get_int (w);117 Add (u,v,w), add (v,u,w);118 }119 -father[1]=1; dep[1]=1; tot=0; mn[1]=Inf;121memset (Vis,false,sizeof(VIS));D FS1 (1);122memset (Vis,false,sizeof(VIS));D FS2 (1,1);123memset (head2,-1,sizeof(head2));124 Get_int (m); the for(intI=1; i<=m;i++) Solve ();126 return 0;127}
C + +
Bzoj 2286 tree chain split +dfs sequence + virtual tree + Tree DP