bzoj2286:[Sdoi2011]消耗战
虚树+树形DP乱搞
代码有些丑...
#include<bits/stdc++.h> using namespace std; long long n,m,len2=0,pp,trs[2500020],d[2500020],lin2[2500200],q[2500020],p[550020][26],lin[800020],len=0,dfsin[800020],cnt=0,h[800020]; long long w[2500200],f[2500020]; bool f2[5000200]; struct one { long long y,next; long long v; }; one e[5000020]; bool cmp(long long a,long long b) {return dfsin[a]<dfsin[b];} struct newtree { long long y,next,v; }; newtree tree[5000020]; void insert(long long x,long long y,long long v) { e[++len].next=lin[x]; lin[x]=len; e[len].y=y; e[len].v=v; } void insert2(long long x,long long y) { tree[++len2].next=lin2[x]; lin2[x]=len2; tree[len2].y=y; } void dfs(long long id,long long v,long long fa) { dfsin[id]=++cnt; for(long long i=lin[id];i;i=e[i].next) { if(fa==e[i].y)continue; d[e[i].y]=d[id]+1; p[e[i].y][0]=id; f[e[i].y]=min(v,e[i].v); dfs(e[i].y,min(v,e[i].v),id); } } void init() { for(long long j=1;(1<<j)<=n;j++) { for(long long i=1;i<=n;i++) { p[i][j]=p[p[i][j-1]][j-1]; } } } long long lca(long long a,long long b) { if(d[a]>d[b])swap(a,b); long long F=d[b]-d[a]; for(long long i=0;(1<<i)<=F;i++)if((1<<i)&F)b=p[b][i]; if(a!=b) { for(long long i=log2(n);i>=0;i--) { if(p[a][i]!=p[b][i]){a=p[a][i];b=p[b][i];} } a=p[a][0]; } return a; } void DP(long long p) { if(f2[p]) { w[p]=f[p]; return; } long long ans=0; for(long long i=lin2[p];i;i=tree[i].next) { DP(tree[i].y); ans+=w[tree[i].y]; } if(!ans)w[p]=f[p]; else w[p]=min(f[p],ans); } int main() { //freopen("xf.in","r",stdin); //freopen("xf.out","w",stdout); scanf("%lld",&n); f[0]=999999999999; long long x,y,v; insert(0,1,999999999999); insert(1,0,999999999999); for(long long i=1;i<n;i++) { scanf("%lld%lld%lld",&x,&y,&v); insert(x,y,v);insert(y,x,v); } dfs(0,999999999999,0); init(); scanf("%lld",&m); for(long long i=1;i<=m;i++) { scanf("%lld",&pp); for(long long i=1;i<=pp;i++) { scanf("%lld",&h[i]); } sort(h+1,h+pp+1,cmp); long long sz=0; trs[sz++]=0; long long tail=0; for(long long i=1;i<=pp;i++) { //记得要初始化 long long LCA=lca(trs[sz-1],h[i]); if(LCA==trs[sz-1])trs[sz++]=h[i]; else { while(sz>=2&&d[trs[sz-2]]>=d[LCA]) { insert2(trs[sz-2],trs[sz-1]); sz--; q[++tail]=trs[sz]; } if(LCA!=trs[sz-1]) { insert2(LCA,trs[--sz]); q[++tail]=trs[sz]; trs[sz++]=LCA; } trs[sz++]=h[i]; } } for(long long i=0;i<sz-1;i++) { insert2(trs[i],trs[i+1]); q[++tail]=trs[i]; } q[++tail]=trs[sz-1]; for(long long i=1;i<=pp;i++)f2[h[i]]=true; DP(0); for(long long i=1;i<=pp;i++)f2[h[i]]=false; printf("%lld\n",w[0]); len2=0; for(long long i=1;i<=tail;i++) lin2[q[i]]=0; } return 0; }