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;
}

  

posted @ 2018-02-24 09:22  mybing  阅读(139)  评论(0编辑  收藏  举报