bzoj 3611: [Heoi2014]大工程
虚树,跪,貌似搞出虚树之后的DP挺好想的,然而蒟蒻还是虚的扒了题解,,
1 #include <bits/stdc++.h> 2 #define LL long long 3 #define inf 0x3f3f3f3f 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 LL tot; 13 int bin[20]; 14 int n,K,top,cnt,q,ind,ans1,ans2; 15 int head[1000005],rehead[1000005],v[1000005]; 16 int mx[1000005],mn[1000005]; 17 int fa[1000005][20],deep[1000005],dfn[1000005],st[1000005],h[1000005]; 18 LL size[1000005],f[1000005]; 19 struct edge{ 20 int to,next,v; 21 }e[2000005],re[2000005]; 22 void insert2(int x, int y) 23 { 24 if (x==y) return; 25 re[++cnt].next=rehead[x]; re[cnt].to=y; rehead[x]=cnt; re[cnt].v=deep[y]-deep[x]; 26 } 27 void insert(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;} 28 void pre_dfs(int x) 29 { 30 dfn[x]=++ind; 31 for (int i=1; bin[i]<=deep[x]; i++) 32 fa[x][i]=fa[fa[x][i-1]][i-1]; 33 for (int i=head[x];i;i=e[i].next) 34 { 35 if (e[i].to==fa[x][0]) continue; 36 deep[e[i].to]=deep[x]+1; 37 fa[e[i].to][0]=x; 38 size[x]+=size[e[i].to]; 39 pre_dfs(e[i].to); 40 } 41 } 42 int lca(int x, int y) 43 { 44 if (deep[x]<deep[y]) swap(x,y); 45 int t=deep[x]-deep[y]; 46 for (int i=0; bin[i]<=t; i++) 47 if (t&(1<<i)) x=fa[x][i]; 48 for (int i=18; i>=0; i--) 49 if (fa[x][i]!=fa[y][i]) 50 x=fa[x][i],y=fa[y][i]; 51 return x==y?x:fa[x][0]; 52 } 53 bool cmp(int a, int b){return dfn[a]<dfn[b];} 54 void dp(int x) 55 { 56 size[x]=v[x]; f[x]=0; 57 mn[x]=v[x]?0:inf; 58 mx[x]=v[x]?0:-inf; 59 for (int i=rehead[x];i;i=re[i].next) 60 { 61 dp(re[i].to); 62 tot+=(f[x]+size[x]*re[i].v)*size[re[i].to]+f[re[i].to]*size[x]; 63 size[x]+=size[re[i].to]; 64 f[x]+=f[re[i].to]+size[re[i].to]*re[i].v; 65 ans1=min(ans1,mn[x]+mn[re[i].to]+re[i].v); 66 ans2=max(ans2,mx[x]+mx[re[i].to]+re[i].v); 67 mn[x]=min(mn[x],mn[re[i].to]+re[i].v); 68 mx[x]=max(mx[x],mx[re[i].to]+re[i].v); 69 } 70 rehead[x]=0; 71 } 72 void solve() 73 { 74 int K=ra(); 75 for (int i=1; i<=K; i++) v[h[i]=ra()]=1; 76 sort(h+1,h+K+1,cmp); 77 top=cnt=0; 78 st[++top]=1; 79 for (int i=1; i<=K; i++) 80 { 81 int x=h[i]; int f=lca(x,st[top]); 82 if (f==st[top]) {st[++top]=x; continue;} 83 while (f==lca(x,st[top-1])) 84 { 85 insert2(st[top-1],st[top]); 86 top--; f=lca(x,st[top]); 87 } 88 insert2(f,st[top]); st[top]=f; st[++top]=x; 89 } 90 if (top) while (--top) insert2(st[top],st[top+1]); 91 ans1=inf; ans2=-inf; tot=0; 92 dp(1); 93 printf("%lld ",tot); printf("%d %d\n",ans1,ans2); 94 for (int i=1; i<=K; i++) v[h[i]]=0; 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(); 103 insert(x,y); insert(y,x); 104 } 105 pre_dfs(1); 106 int Q=ra(); 107 for (int i=1; i<=Q; i++) solve(); 108 return 0; 109 }