Tree chain problem

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1798    Accepted Submission(s): 585

Problem Description

Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.
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
 

Input

The input consists of several test cases. The first line of input gives the number of test cases T (T<=10).
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.
 

Output

For each tests:
A single integer, the maximum number of paths.
 

Sample Input

1
7 3
1 2
1 3
2 4
2 5
3 6
3 7
2 3 4
4 5 3
6 7 3
 

Sample Output

6

Hint

Stack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")

 

Author

FZUACM
 

Source

对于每条链u,v,w,我们只在lca(u,v)的顶点上处理它

让dp[i]表示以i为根的子树的最大值,sum[i]表示dp[vi]的和(vi为i的儿子们)

则i点有两种决策,一种是不选以i为lca的链,则dp[i]=sum[i]。

另一种是选一条以i为lca的链,那么有转移方程:dp[i]=sigma(dp[vj])+sigma(sum[kj])+w。(sigma表示累加,vj表示那些不在链上的孩子们,kj表示在链上的孩子们)

为了便于计算,我们处理出dp[i]=sum[i]-sigma(dp[k]-sum[k])+w=sum[i]+sigma(sum[k]-dp[k])+w。

利用dfs序和树状数组可以logn算出sigma(sum[k]-dp[k])。

 //2017-09-13
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int N = ;
const int LOG_N = ; int head[N], tot;
struct Edge{
int v, next;
}edge[N<<]; void add_edge(int u, int v){
edge[tot].v = v;
edge[tot].next = head[u];
head[u] = tot++;
} int in[N], out[N], idx, depth[N], father[N][LOG_N];
void dfs(int u, int fa){
in[u] = ++idx;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].v;
if(v == fa)continue;
depth[v] = depth[u]+;
father[v][]= u;
for(int j = ; j < LOG_N; j++)
father[v][j] = father[father[v][j-]][j-];
dfs(v, u);
}
out[u] = ++idx;
} int tree[N]; int lowbit(int x){
return x&(-x);
} void add(int pos, int val){
for(int i = pos; i <= N; i+=lowbit(i))
tree[i] += val;
} int query(int l){
int sum = ;
for(int i = l; i > ; i-=lowbit(i))
sum += tree[i];
return sum;
} int lca(int u, int v){
if(depth[u] < depth[v])
swap(u, v);
for(int i = LOG_N-; i >= ; i--){
if(depth[father[u][i]] >= depth[v])
u = father[u][i];
}
if(u == v)return u;
for(int i = LOG_N-; i >= ; i--){
if(father[u][i] != father[v][i]){
u = father[u][i];
v = father[v][i];
}
}
return father[u][];
}
struct Chain{
int u, v, w;
}chain[N];
vector<int> vec[N]; int dp[N], sum[N];
void solve(int u, int fa){
dp[u] = sum[u] = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].v;
if(v == fa)continue;
solve(v, u);
sum[u] += dp[v];
}
dp[u] = sum[u];
for(auto &pos: vec[u]){
int a = chain[pos].u;
int b = chain[pos].v;
int c = chain[pos].w;
dp[u] = max(dp[u], sum[u]+query(in[a])+query(in[b])+c);
}
add(in[u], sum[u]-dp[u]);
add(out[u], dp[u]-sum[u]);
} int T, n, m;
void init(){
tot = ;
idx = ;
depth[] = ;
for(int i = ; i <= n; i++)
vec[i].clear();
memset(head, -, sizeof(head));
memset(dp, , sizeof());
memset(sum, , sizeof());
memset(tree, , sizeof(tree));
} int main()
{
freopen("inputB.txt", "r", stdin);
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
init();
int u, v;
for(int i = ; i < n-; i++){
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
dfs(, );
for(int i = ; i < m; i++){
scanf("%d%d%d", &chain[i].u, &chain[i].v, &chain[i].w);
vec[lca(chain[i].u, chain[i].v)].push_back(i);
}
solve(, );
printf("%d\n", dp[]);
} return ;
}

HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)的更多相关文章

  1. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  2. codeforces 570 D. Tree Requests 树状数组+dfs搜索序

    链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...

  3. E - Apple Tree(树状数组+DFS序)

    There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...

  4. POJ 3321 Apple Tree (树状数组+dfs序)

    题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...

  5. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  6. 【BZOJ-1103】大都市meg 树状数组 + DFS序

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2009  Solved: 1056[Submit][Sta ...

  7. [luogu P3787][新创无际夏日公开赛] 冰精冻西瓜 [树状数组][dfs序]

    题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...

  8. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  9. BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...

随机推荐

  1. kmp循环节

    循环判断   i%(i-next[i]) == 0 && next[i] != 0 循环长度  i-next[i];

  2. 微服务ServiceMesh及三种模式介绍

    1. 前言 今年,ServiceMesh(服务网格)概念在社区里头非常火,有人提出2018年是ServiceMesh年,还有人提出ServiceMesh是下一代的微服务架构基础.作为架构师,如果你现在 ...

  3. 一次对SNMP服务的渗透测试

    Hacking SNMP Service - The Post Exploitation :Attacking Network - Network Pentesting原文地址:http://www. ...

  4. Javascript高级编程学习笔记(13)—— 引用类型(2)Array类型

    除了Object类型之外ECMA中最常用的引用类型可能就是Array类型了 并且ECMA中的数组类型和其他大多数编程语言的数组类型存在着很大的区别 今天就介绍一下JS中的Array的特别之处 区别 1 ...

  5. 腾讯大数据之TDW计算引擎解析——Shuffle

    转自 https://www.csdn.net/article/2014-05-19/2819831-TDW-Shuffle/1 摘要:腾讯分布式数据仓库基于开源软件Hadoop和Hive进行构建,T ...

  6. Shell-9--条件测试

  7. kubernetes集群搭建(1):环境准备

    了解kubernets 本次搭建采用的是1个master节点,2个node节点,一个私有docker仓库 1.设置各节点ip信息 2.设置hostname(其它节点也需修改) vi /etc/sysc ...

  8. mybatis 详解(一)

    http://www.cnblogs.com/ysocean/p/7271600.html 1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目 ...

  9. 简介 - RESTful

    RESTful REST(Representational State Transfer,表现层状态转化),可以简单理解为"资源在网络中以某种表现形式进行状态转移" Resourc ...

  10. Python常用模块——json & pickle

    序列化模块 1.什么是序列化-------将原本的字典,列表等对象转换成一个字符串的过程就叫做序列化 2.序列化的目的 1.以某种存储形式使自定义对象持久化 2.将对象从一个地方传递到另一个地方 3. ...