洛谷 3177 [HAOI2015] 树上染色
题目描述
有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。
输入输出格式
输入格式:
第一行包含两个整数 N, K 。接下来 N-1 行每行三个正整数 fr, to, dis , 表示该树中存在一条长度为 dis 的边 (fr, to) 。输入保证所有点之间是联通的。
输出格式:
输出一个正整数,表示收益的最大值。
输入输出样例
- 3 1
- 1 2 1
- 1 3 2
- 3
说明
对于 100% 的数据, 0<=K<=N <=2000
题解:
最终的收益等于每一条边的收益(权值乘以被用到的次数)的和,假设dp[i][j]表示以i为根的子树内有j个点为黑点时边的收益,从叶子到根的顺序计算每条边的收益,遍历到i点时,i的子树里的边已经被计算过了,i到其儿子的边被新加了进来,用这些新加的边的收益和子树的收益更新以i为根的子树的收益。
转移方程为dp[i][j]=dp[k][l]+边权*子树内黑点*子树外黑点+边权*子树内白点*子树外白点。
一开始我以为自己计算的是答案的两倍,这样智障了很久,后来把/2删掉后过了,我又仔细思考了一下,我是一条边一条边的算的,所以只会算一次。
- #include<algorithm>
- #include<iostream>
- #include<cstdlib>
- #include<cstdio>
- #define nn 2010
- #define mm 4010
- #define lo long long
- #define inf -100000000
- using namespace std;
- int e=0;
- int fir[nn],nxt[mm],to[mm],w[mm],size[nn],n,k;
- lo dp[nn][nn];
- bool vis[nn];
- int get()
- {
- int ans=0,f=1;char ch=getchar();
- while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
- while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
- return ans*f;
- }
- void add(int a,int b,int c)
- {
- nxt[++e]=fir[a];fir[a]=e;to[e]=b;w[e]=c;
- nxt[++e]=fir[b];fir[b]=e;to[e]=a;w[e]=c;
- }
- void dfs(int o)
- {
- size[o]=1;
- for(int i=fir[o];i;i=nxt[i])
- if(!vis[to[i]])
- {
- vis[to[i]]=1;
- dfs(to[i]);
- size[o]+=size[to[i]];
- }
- }
- void solve(int o)
- {
- dp[o][0]=0;
- dp[o][1]=0;
- for(int i=fir[o];i;i=nxt[i])
- if(size[o]>size[to[i]])
- {
- solve(to[i]);
- for(int j=size[o];j>=0;j--) //把size[o]写成了size[i]
- for(int p=0;p<=size[to[i]]&&p<=j;p++)
- dp[o][j]=max(dp[o][j],dp[to[i]][p]+dp[o][j-p]+(lo)p*(k-p)*w[i]+(lo)w[i]*(size[to[i]]-p)*(n-k-size[to[i]]+p));
- }
- }
- int main()
- {
- n=get(),k=get();
- int a,b,c;
- for(int i=1;i<n;i++)
- {
- a=get();b=get();c=get();
- add(a,b,c);
- }
- vis[1]=1;
- dfs(1);
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- dp[i][j]=inf;
- solve(1);
- printf("%lld",dp[1][k]);
- return 0;
- }
洛谷 3177 [HAOI2015] 树上染色的更多相关文章
- BZOJ4033或洛谷3177 [HAOI2015]树上染色
BZOJ原题链接 洛谷原题链接 很明显的树形\(DP\). 因为记录每个点的贡献很难,所以我们可以统计每条边的贡献. 对于每一条边,设边一侧的黑点有\(B_x\)个,白点有\(W_x\),另一侧黑点有 ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P3177 [HAOI2015]树上染色
题目链接 题目描述 有一棵点数为 \(N\) 的树,树边有边权.给你一个在 \(0~ N\) 之内的正整数 \(K\) ,你要在这棵树中选择 \(K\)个点,将其染成黑色,并将其他 的\(N-K\)个 ...
- 洛谷P3177 [HAOI2015]树上染色(树形dp)
题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...
- 洛谷P3177 [HAOI2015]树上染色(树上背包)
题意 题目链接 Sol 比较套路吧,设\(f[i][j]\)表示以\(i\)为根的子树中选了\(j\)个黑点对答案的贡献 然后考虑每条边的贡献,边的两边的答案都是可以算出来的 转移的时候背包一下. # ...
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- 洛谷P3178 [HAOI2015]树上操作
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
- 洛谷P3178 [HAOI2015]树上操作(线段树)
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
- 洛谷 P3178 [HAOI2015]树上操作
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
随机推荐
- 初探iview
我的js功力还是TCL,太差了~ 运行iview官网例子还有它的工程文件都运行不出来.我非常感谢那些无私开源的博主,它们无私分享自己的技术,让我学到了很多东西. iview是vue的一个UI框架之一, ...
- Spring_JDBC连接
1.导入jarbao 2.创建pojo,dao,Impl package com.tanlei.pojo; public class Department { private Long deptId; ...
- 【JZOJ2758】【SDOI2012】走迷宫(labyrinth)
╰( ̄▽ ̄)╭ Morenan 被困在了一个迷宫里. 迷宫可以视为 N 个点 M 条边的有向图,其中 Morena n处于起点 S , 迷宫的终点设为 T . 可惜的是 , Morenan 非常的脑小 ...
- LocalDateTime计算时间差
LocalDateTime 为java8的新特性之一 LocalDateTime.now() 获得当前时间 java.time.Duration duration = java.time.Durati ...
- 信息摘要算法 MessageDigestUtil
package com.xgh.message.digest.test; import java.math.BigInteger; import java.security.MessageDigest ...
- 使用virtualenv使得Python2和Python3并存
1:下载python3源码并安装 wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz .tgz cd Python-.tgz . ...
- Vim学习与总结
1. :w 后面可以加文件名 2. 使用hjkl 来移动光标,当然你也可以使用箭头.j就是向下的箭头,k是向上,h向左, l向右 3. :help <command> → 显示相关命令的 ...
- AtCoder Regular Contest 090 D - People on a Line
D - People on a Line Problem Statement There are N people standing on the x-axis. Let the coordinate ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第五章:渲染流水线
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第五章:渲染流水线 学习目标 了解几个用以表达真实场景的标志和2D图像 ...
- MaxCompute 图计算用户手册(下)
示例程序 强连通分量 在有向图中,如果从任意一个顶点出发,都能通过图中的边到达图中的每一个顶点,则称之为强连通图.一张有向图的顶点数极大的强连通子图称为强连通分量.此算法示例基于 parallel C ...