zoukankan      html  css  js  c++  java
  • 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
    ",w[0]);
    		len2=0;
    		for(long long i=1;i<=tail;i++)
    			lin2[q[i]]=0;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    bzoj3675 [Apio2014]序列分割
    bzoj4010 [HNOI2015]菜肴制作
    bzoj4011 [HNOI2015]落忆枫音
    bzoj100题
    JSP—内置对象
    集合框架—常用的map集合
    集合框架—HashMap
    集合框架—代码—用各种集合进行排序
    集合框架—2种排序比较器
    array
  • 原文地址:https://www.cnblogs.com/mybing/p/8464092.html
Copyright © 2011-2022 走看看