虚树,,,,还是虚树2333
虚树这个东西嘛,就把关键点拿出来,利用树链上有前缀和的性质,在不改变原来相对位置的情况下,添加尽量少的点,使关键点构成新的(虚)树。。
(然而感觉虚树并不虚的,,我才虚啊。。)
这个题虚树搞出来之后随便搞搞就行。。。
1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define LL long long 4 using namespace std; 5 inline int ra() 6 { 7 int x=0,f=1; char ch=getchar(); 8 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 9 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 10 return x*f; 11 } 12 int bin[20]; 13 int n,m,cnt,ind,top; 14 int head[250005],rehead[250005],fa[250005][20]; 15 LL mn[250005],f[250005]; 16 int h[250005],dfn[250005],deep[250005]; 17 int st[250005]; 18 struct edge{ 19 int to,next,v; 20 }e[500005],re[500005]; 21 void insert(int x, int y, int v){ 22 e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt; e[cnt].v=v; 23 } 24 void insert2(int x, int y) 25 { 26 if (x==y) return; 27 re[++cnt].to=y; re[cnt].next=rehead[x]; rehead[x]=cnt; 28 } 29 void pre(int x) 30 { 31 dfn[x]=++ind; 32 for (int i=1; bin[i]<=deep[x]; i++) 33 fa[x][i]=fa[fa[x][i-1]][i-1]; 34 for (int i=head[x];i;i=e[i].next) 35 { 36 if (e[i].to==fa[x][0]) continue; 37 fa[e[i].to][0]=x; 38 mn[e[i].to]=min(mn[x],(LL)e[i].v); 39 deep[e[i].to]=deep[x]+1; 40 pre(e[i].to); 41 } 42 } 43 int lca(int x, int y) 44 { 45 if (deep[x]<deep[y]) swap(x,y); 46 int t=deep[x]-deep[y]; 47 for (int i=0; (1<<i)<=t; i++) 48 if ((1<<i)&t) x=fa[x][i]; 49 for (int i=19; i>=0; i--) 50 if (fa[x][i]!=fa[y][i]) 51 x=fa[x][i],y=fa[y][i]; 52 if (x==y) return x; 53 return fa[x][0]; 54 } 55 void dp(int x) 56 { 57 f[x]=mn[x]; 58 LL tmp=0; 59 for (int i=rehead[x]; i; i=re[i].next) 60 { 61 dp(re[i].to); tmp+=f[re[i].to]; 62 } 63 rehead[x]=0; 64 if (tmp==0) f[x]=mn[x]; 65 else if (tmp<=f[x]) f[x]=tmp; 66 } 67 bool cmp(int a, int b){return dfn[a]<dfn[b];} 68 void solve() 69 { 70 int K=ra(); cnt=0; 71 for (int i=1; i<=K; i++) h[i]=ra(); 72 sort(h+1,h+K+1,cmp); 73 int tot=0; h[++tot]=h[1]; 74 for (int i=2; i<=K; i++) 75 if (lca(h[tot],h[i])!=h[tot]) h[++tot]=h[i]; 76 st[++top]=1; 77 for (int i=1; i<=tot; i++) 78 { 79 int now=h[i],f=lca(now,st[top]); 80 while (1) 81 { 82 if (deep[f]>=deep[st[top-1]]) 83 { 84 insert2(f,st[top--]); 85 if (st[top]!=f) st[++top]=f; 86 break; 87 } 88 insert2(st[top-1],st[top]); top--; 89 } 90 if (st[top]!=now) st[++top]=now; 91 } 92 while (--top) insert2(st[top],st[top+1]); 93 dp(1); 94 printf("%lld ",f[1]); 95 } 96 int main(int argc, char const *argv[]) 97 { 98 bin[0]=1; for (int i=1; i<=20; i++) bin[i]=bin[i-1]<<1; 99 n=ra(); 100 for (int i=1; i<n; i++) 101 { 102 int x=ra(),y=ra(); int v=ra(); 103 insert(x,y,v); insert(y,x,v); 104 } 105 mn[1]=1e60; pre(1); m=ra(); 106 for (int i=1; i<=m; i++) solve(); 107 return 0; 108 }