zoukankan      html  css  js  c++  java
  • [HAOI2015]树上染色

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    3 1
    1 2 1
    1 3 2
    输出样例#1: 复制
    3

    说明

    对于 100% 的数据, 0<=K<=N <=2000

    设$f[i][j]$表示i的子树选了j个黑点的边贡献和

    因为点的贡献不好维护

    如果一条边,它下面有j个黑点,那么这条边的贡献:

    1.w*j*(k-j)  黑点贡献

    2.w*(size[v]-j)*(n-size[v]-k+j)  白点贡献

    然后树形背包

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long lol;
     8 struct Node
     9 {
    10   int next,to;
    11   int dis;
    12 }edge[4001];
    13 lol ans,f[2001][2001];
    14 int size[2001],k;
    15 int num,head[2001],n;
    16 void add(int u,int v,int d)
    17 {
    18   num++;
    19   edge[num].next=head[u];
    20   head[u]=num;
    21   edge[num].to=v;
    22   edge[num].dis=d;
    23 }
    24 void dfs(int x,int pa)
    25 {int i;
    26   int j,l;
    27   size[x]=1;
    28   f[x][0]=f[x][1]=0;
    29   for (i=head[x];i;i=edge[i].next)
    30     {
    31       int v=edge[i].to;
    32       if (v==pa) continue;
    33       dfs(v,x);
    34       size[x]+=size[v];
    35       for (j=min(k,size[x]);j>=0;j--)
    36     {
    37       for (l=0;l<=min(j,size[v]);l++)
    38         if (f[x][j-l]!=-1&&f[v][l]!=-1)
    39         {
    40           lol val=1ll*l*(k-l)*edge[i].dis+1ll*(size[v]-l)*(n-k-size[v]+l)*edge[i].dis;
    41           f[x][j]=max(f[x][j],f[x][j-l]+f[v][l]+val);
    42         }
    43     }
    44     }
    45 }
    46 int main()
    47 {int i,u,v;
    48   int d;
    49   cin>>n>>k;
    50   for (i=1;i<=n-1;i++)
    51     {
    52       scanf("%d%d%d",&u,&v,&d);
    53       add(u,v,d);add(v,u,d);
    54     }
    55   memset(f,-1,sizeof(f));
    56   dfs(1,0);
    57   cout<<f[1][k];
    58 }
  • 相关阅读:
    linux下内存检测工具valgrind
    c语言可变参数与宏定义
    rabbitmq学习之路-rabbitmqctl
    linux/mac下命令行rm回收站--rmtrash
    Python之路【第十一篇】: 进程与线程理论篇
    Python之路【第十一篇】: 进程与线程
    Git常用命令
    Python之路【第十篇】: python基础之socket编程
    Python之路【第九篇】:面向对象进阶
    Python之路【第八篇】:面向对象的程序设计
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8964157.html
Copyright © 2011-2022 走看看