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. ASP.NET Core 请求/查询/响应参数格式转换(下划线命名)

    业务场景: 在 ASP.NET Core 项目中,所有的代码都是骆驼命名,比如userName, UserName,但对于 WebApi 项目来说,因为业务需要,一些请求.查询和响应参数的格式需要转换 ...

  2. MFC中的Debug Assertion Failed 如何查找原因

    编写MFC程序时经常会遇到下图所示的断言失败问题 报错对话框中给出了一个目录,是在F盘,但是查找之后会发现电脑里可能根本没有这个目录. 最后发现可以在VS的安装目录下找到这个文件: \atlmfc\s ...

  3. 微信小程序scroll-view 横向和纵向scroll-view组件

    scroll-view为滚动视图,分为水平滚动和垂直滚动.注意滚动视图垂直滚动时一定要设置高度否则的话scroll-view不会生效.滚动视图常用的地方一般都是Item项比较多的界面,比如我的模块 主 ...

  4. [Swift]LaunchScreen.storyboard如何跳转到到Main.storyboard

    在加载App时,首先读取[LaunchScreen.storyboard]中的内容, 在App加载到内存之后,自动读取[Main.storyboard]中的初始视图控制器, 用于替换原来的[Launc ...

  5. Swift 里 Dictionary

    Dictionary uses two storage schemes: native storage and Cocoa storage. 只看 native storage 的,也就是和 OC 无 ...

  6. BonnMotion支持的几种移动模型

    BonnMotion是一款基于java的移动场景产生和分析工具,常用来研究mobile ad hoc network的特征.其产生的移动场景可以导入到几款网络模拟器中进行模拟分析,例如:NS2,NS3 ...

  7. SqlServer 更改数据库名称

    1.首先选中需要更改数据库右击属性找到文件, 此处可直接修改数据库逻辑名称 2.选中数据库右击选择重命名修改数据库名称. 3.将数据库进行分离,找到数据库文件mdf与ldf文件,直接更改文件名称 4. ...

  8. [EXP]McAfee ePO 5.9.1 - Registered Executable Local Access Bypass

    # Exploit Title: McAfee ePO 5.9.1 Registered Executable Local Access Bypass # Date: 2019-03-07 # Exp ...

  9. .NetCore使用skywalking实现实时性能监控

    一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...

  10. ElasticSearch实战-编码实践

    1.概述 前面在<ElasticSearch实战-入门>中给大家分享如何搭建这样一个集群,在完成集群的搭建后,今天给大家分享如何实现对应的业务功能模块,下面是今天的分享内容,目录如下所示: ...