hdu5293(2015多校1)--Tree chain problem(树状dp)
Tree chain problem
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 262 Accepted Submission(s): 59
There are m chain on the tree, Each chain has a certain weight. Coco would like to pick out some chains any two of which do not share common vertices.
Find out the maximum sum of the weight Coco can pick
For each tests:
First line two positive integers n, m.(1<=n,m<=100000)
The following (n - 1) lines contain 2 integers ai bi denoting an edge between vertices ai and bi (1≤ai,bi≤n),
Next m lines each three numbers u, v and val(1≤u,v≤n,0<val<1000), represent the two end points and the weight of a tree chain.
A single integer, the maximum number of paths.
1
7 3
1 2
1 3
2 4
2 5
3 6
3 7
2 3 4
4 5 3
6 7 3
6HintStack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")
题目大意:有一颗n个节点的数。给出n-1条边(无向),还有m条链,每条链链接两个顶点(按lca的方式链接)。链存在一个权值w。如今想要挑选一些链,挑选的链中不能出现同样的节点,问能够挑选出的最大的权重是多少?
要求权值最大,依照树形dp的思路去考虑,那么dp[i]为以第i个点位根节点的子树的最优解。dp[i]的状态转移公式,有两种可能,第一种:第i个节点上不出现链,那么dp[i] = ∑(dp[k] | k为i的子节点);另外一种:第i个节点上出现链。假设选择增加这条链,那么dp[i] = w(链的权值) + ∑(dp[k] | k为链上的节点的子节点) = w + ∑(sum[k]
| k为链上的节点 ) - ∑(dp[k] | k为链上的节点) 。sum[i]表示i节点的全部子节点的dp和,在 ∑(sum[k] | k为链上的节点 ) - ∑(dp[k] | k为链上的节点) 中减去的dp[k]会由它的父节点的sum补全。
这样就得到了状态转移公式。
还有要计算给出的链的两个顶点的lca(用于更新dp的值),在更新dp值的时候须要计算链上节点的(sun的和)(dp的和),使用树状数组来计算。对全部节点进行dfs。对点进行又一次编号。每到达一个点和每离开一个点都要编号,记录在l[i]和r[i]中,当计算玩一个sum[i]值后。加到树状数组c1中(l[i]位置加正值,r[i]位置加负值)。计算完一个dp[i]值后,加到树状数组c2中(l[i]位置加正值,r[i]位置加负值)。依照新的编号进行树状数组计算区间和。也就能够得到链上的节点的和
总结:
1、建树,题目给出的(无向边)。要加双边
2、dfs,建立rmq[i][j]:i节点的第2^j个父节点,对节点又一次编号
3、对给出的两个顶点求lca。(代码中用rmq求lca)
4、树状数组,求区间和。
5、深搜,完毕树形dp,按状态转移方程计算每个节点的值,使用树状数组计算链上节点的和
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std ;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define maxn 200050
struct E{
int v , next ;
}edge[maxn] ;
int head[maxn] , cnt ;
struct node{
int u , v , w ;
int lca ;
}p[maxn] ;
int dep[maxn] , rmq[maxn][20] ;
int l[100010] , r[maxn] , cid ;
vector <int> vec[maxn] ;
int dp[maxn] , sum[maxn] ;
int c1[maxn] , c2[maxn] ;
void add_E(int u,int v) {
edge[cnt].v = v ;
edge[cnt].next = head[u] ; head[u] = cnt++ ;
edge[cnt].v = u ;
edge[cnt].next = head[v] ; head[v] = cnt++ ;
}
void dfs(int fa,int u) {
l[u] = ++cid ;
int i , j , v ;
for(i = head[u] ; i != -1 ; i = edge[i].next) {
v = edge[i].v ;
if( v == fa ) continue ;
dep[v] = dep[u] + 1 ;
rmq[v][0] = u ;
for(j = 1 ; j < 20 ; j++)
rmq[v][j] = rmq[ rmq[v][j-1] ][j-1] ;
dfs(u,v) ;
}
r[u] = ++cid ;
}
int lca(int u,int v) {
if( dep[u] < dep[v] )
swap(u,v) ;
int i , j ;
for(i = 19 ; i >= 0 ; i--) {
if( dep[ rmq[u][i] ] >= dep[v] )
u = rmq[u][i] ;
if( u == v ) return u ;
}
for(i = 19 ; i >= 0 ; i--) {
if( rmq[u][i] != rmq[v][i] ){
u = rmq[u][i] ;
v = rmq[v][i] ;
}
}
return rmq[u][0] ;
}
int lowbit(int x) {
return x & -x ;
}
void add(int i,int k,int *c,int n) {
while( i <= n ) {
c[i] += k ;
i += lowbit(i) ;
}
}
int getsum(int i,int *c) {
int ans = 0 ;
while( i ) {
ans += c[i] ;
i -= lowbit(i) ;
}
return ans ;
}
void solve(int fa,int s,int n) {
dp[s] = sum[s] = 0 ;
int i , j , u , v , temp ;
for(i = head[s] ; i != -1 ;i = edge[i].next) {
v = edge[i].v ;
if( v == fa ) continue ;
solve(s,v,n) ;
sum[s] += dp[v] ;
}
dp[s] = sum[s] ;
for(i = 0 ; i < vec[s].size() ; i++) {
u = p[ vec[s][i] ].u ;
v = p[ vec[s][i] ].v ;
temp = getsum(l[u],c1) + getsum(l[v],c1) - getsum(l[u],c2) - getsum(l[v],c2) + sum[s] ;
dp[s] = max(dp[s],temp+p[vec[s][i]].w) ;
}
add(l[s],sum[s],c1,n*2) ;
add(r[s],-sum[s],c1,n*2) ;
add(l[s],dp[s],c2,n*2) ;
add(r[s],-dp[s],c2,n*2) ;
}
void init(int n) {
memset(head,-1,sizeof(head)) ;
memset(rmq,0,sizeof(rmq)) ;
memset(c1,0,sizeof(c1)) ;
memset(c2,0,sizeof(c2)) ;
cnt = cid = 0 ;
dep[1] = 1 ;
rmq[1][0] = 1 ;
for(int i = 1 ; i <= n ; i++)
vec[i].clear() ;
return ;
}
int main() {
int t , n , m ;
int i , j , u , v , w ;
//freopen("1006.in","r",stdin) ;
//freopen("t.out","w",stdout) ;
scanf("%d", &t) ;
while( t-- ) {
scanf("%d %d", &n, &m) ;
init(n) ;
for(i = 1 ; i < n ; i++) {
scanf("%d %d", &u, &v) ;
add_E(u,v) ;
}
dfs(-1,1) ;
for(i = 0 ; i < m ; i++) {
scanf("%d %d %d", &p[i].u, &p[i].v, &p[i].w) ;
p[i].lca = lca(p[i].u,p[i].v) ;
vec[ p[i].lca ].push_back(i) ;
}
solve(-1,1,n) ;
printf("%d\n", dp[1]) ;
}
return 0 ;
}
hdu5293(2015多校1)--Tree chain problem(树状dp)的更多相关文章
- 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集
[题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- poj2486--Apple Tree(树状dp)
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7789 Accepted: 2606 Descri ...
- 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)
题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- [poj3321]Apple Tree(dfs序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26762 Accepted: 7947 Descr ...
- POJ3321Apple Tree Dfs序 树状数组
出自——博客园-zhouzhendong ~去博客园看该题解~ 题目 POJ3321 Apple Tree 题意概括 有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作: 1.改变其 ...
随机推荐
- 解决网页中Waiting (TTFB)数据加载过慢的问题
解决网页中Waiting (TTFB)数据加载过慢的问题 最近做了一个网页,在本地测试良好,数据可以得到很快的反馈,但是当部署到云端Linux上时候,就会出现加载缓慢的问题.本地测试,得到数据大概3s ...
- js表单提交回调函数
在研究表单的时候发现一个有意思的东西——在表单提交的时候如何保证数据全部提交完毕才会清空? 我们常用的<input type="reset" value="重置&q ...
- bzoj 1449 费用流
思路:先把没有进行的场次规定双方都为负,对于x胜y负 变为x + 1胜 y - 1 负所需要的代价为 2 * C[ i ] * x - 2 * D[ i ] * y + C[ i ] + D[ i ...
- OpenStack 认证服务 KeyStone部署 (四)
Keystone作用: 用户与认证:用户权限与用户行为跟踪: 服务目录:提供一个服务目录,包括所有服务项和相关Api的断点 SOA相关知识 Keystone主要两大功能用户认证和服务目录(相当于一个注 ...
- Ionic-wechat项目边开发边学(三):自定义样式,指令,服务
摘要 上一篇文章主要介绍了一个ionic项目的标准目录结构,header标签的使用,以及页面之间的切换.这篇文章实现的功能有: 消息数据的获取, 消息列表的展示, 消息标为已读/未读, 主要涉及的到的 ...
- python No migrations to apply
错误显示: “No migrations to apply” 错误情况:python在通过model同步数据库时,提示 No migrations to apply 查看数据库,新表没有被创建,只是 ...
- POJ2912 Rochambeau [扩展域并查集]
题目传送门 Rochambeau Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4463 Accepted: 1545 ...
- Java小对象的解决之道——对象池(Object Pool)的设计与应用
一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...
- 【Floyd】文化之旅
[NOIP2012]文化之旅 题目描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一 种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家).不 ...
- [TCO2013]Block3Checkers
题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍 官方题解——一张图教你做人... 三个棋子将网格边界分成三段,添加障碍后网格中一定 ...