• 【BZOJ4033】[HAOI2015]树上染色 树形DP


    【BZOJ4033】[HAOI2015]树上染色

    Description

    有一棵点数为N的树,树边有边权。给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益。问收益最大值是多少。

    Input

    第一行两个整数N,K。
    接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to)。
    输入保证所有点之间是联通的。
    N<=2000,0<=K<=N

    Output

    输出一个正整数,表示收益的最大值。

    Sample Input

    5 2
    1 2 3
    1 5 1
    2 3 1
    2 4 2

    Sample Output

    17 【样例解释】 将点1,2染黑就能获得最大收益。

    题解:一开始想用网络流,没想到是树形DP~

    用f[i][j]表示在i的子树中选择j个黑点所能得到的最大收益(先只考虑在i子树中的边的贡献),然后跑树形背包即可。

    然后考虑i到父亲的这条边的贡献,即有多少点对经过了这条边。用子树内的黑(白)点*子树外的黑(白)点个数*边权,最后将贡献加到f值上即可。

    注意不要写丑导致复杂度变为O(n^3)哦~

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int maxn=2010;
    typedef long long ll;
    int n,m,cnt;
    int to[maxn<<1],next[maxn<<1],head[maxn],fa[maxn],siz[maxn];
    ll dep[maxn],f[maxn][maxn],val[maxn<<1];
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void dfs(int x)
    {
    	f[x][0]=f[x][1]=0,siz[x]=1;
    	int i,j,k;
    	for(i=head[x];i!=-1;i=next[i])	if(to[i]!=fa[x])
    	{
    		fa[to[i]]=x,dep[to[i]]=val[i],dfs(to[i]);
    		for(k=min(siz[x],m);k>=0;k--)
    			for(j=min(siz[to[i]],m-k);j>=0;j--)
    				f[x][k+j]=max(f[x][k+j],f[x][k]+f[to[i]][j]);
    		siz[x]+=siz[to[i]];
    	}
    	for(i=0;i<=min(siz[x],m);i++)	f[x][i]+=dep[x]*(i*(m-i)+(siz[x]-i)*(n-siz[x]-m+i));
    }
    void add(int a,int b,int c)
    {
    	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,a,b,c;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<n;i++)	a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
    	memset(f,0xfe,sizeof(f));
    	dfs(1);
    	printf("%lld",f[1][m]);
    	return 0;
    }

     

  • 相关阅读:
    C# using的三种用法
    C# 匿名方法和Lambda表达式
    c#中内置委托
    c#委托中的匿名方法和lambda表达式
    java生成条形码
    根据日期筛选和模糊查询
    mysql中ifnull()方法的用法
    mysql数据库中的出发器
    动态SQL之<where>、<if>条件判断
    动态sql
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7500559.html
Copyright © 2020-2023  润新知