zoukankan      html  css  js  c++  java
  • [HDU5290]Bombing plan

    vjudge

    sol

    树DP。
    首先把模型转换成:每个点可以控制与它距离不超过(w_i)的点,先要求选出数量最少的点控制所有点。
    (f[i][-100...100])表示(i)号点向上还可以额外控制距离为(j)的点的选点最少数量。
    (j)为负则表示(j)子树中还有(-(j+1))深度的点没有控制。(比如说,(j=-1)说明(i)号点还没有被控制,(j=-2)说明(i)的儿子还没有被控制)
    这样一来显然(j)越大时的状态是越优的。所以可以对每一层的(f)数组取一个后缀最大值
    然后考虑转移。
    如果选(i)号点:(f[i][w_i]=min(1+sum f[v][-w_i]))
    不选:
    (j>=0)时,(f[i][j]=min(f[x][j+1]+sum f[y][-j]))
    (其中(x)(i)的一个儿子,(y)是剩下的全部儿子)
    (j<0)时,(f[i][j]=min(sum f[v][j+1]))

    直接转啊。

    code

    hdu上要手开无限栈,不然会RE的(别问我怎么知道的)
    如果你也是因为栈溢出RE了就到我代码里面蒯无限栈吧。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #pragma comment(linker, "/STACK:16777216")
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1e5+5;
    int n,w[N],to[N<<1],nxt[N<<1],head[N],cnt,f[N][202],sum[N][202];
    void link(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;}
    void dfs(int u,int fa)
    {
    	memset(f[u],63,sizeof(f[u]));
    	memset(sum[u],0,sizeof(sum[u]));
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=fa)
    		{
    			dfs(to[e],u);
    			for (int i=-100;i<=100;++i)
    				sum[u][i+100]+=f[to[e]][i+100];
    		}
    	for (int i=0;i<=100;++i)
    		for (int e=head[u];e;e=nxt[e])
    			if (to[e]!=fa)
    				f[u][i+100]=min(f[u][i+100],f[to[e]][i+101]+sum[u][-i+100]-f[to[e]][-i+100]);
    	for (int i=-100;i<0;++i) f[u][i+100]=min(f[u][i+100],sum[u][i+101]);
    	f[u][w[u]+100]=min(f[u][w[u]+100],sum[u][-w[u]+100]+1);
    	for (int i=99;i>=-100;--i) f[u][i+100]=min(f[u][i+100],f[u][i+101]);
    }
    int main()
    {
    	while (scanf("%d",&n)!=EOF)
    	{
    		memset(head,0,sizeof(head));cnt=0;
    		for (int i=1;i<=n;++i) w[i]=gi();
    		for (int i=1;i<n;++i)
    		{
    			int u=gi(),v=gi();
    			link(u,v);link(v,u);
    		}
    		dfs(1,0);
    		printf("%d
    ",f[1][100]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python元组、列表、字典
    测试通过Word直接发布博文
    Python环境搭建(windows)
    hdu 4003 Find Metal Mineral 树形DP
    poj 1986 Distance Queries LCA
    poj 1470 Closest Common Ancestors LCA
    poj 1330 Nearest Common Ancestors LCA
    hdu 3046 Pleasant sheep and big big wolf 最小割
    poj 3281 Dining 最大流
    zoj 2760 How Many Shortest Path 最大流
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8659696.html
Copyright © 2011-2022 走看看