HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)
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
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
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
A single integer, the maximum number of paths.
Sample Input
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
Hint
Stack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")
Author
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序)的更多相关文章
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- 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. ...
- POJ 3321 Apple Tree (树状数组+dfs序)
题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- 【BZOJ-1103】大都市meg 树状数组 + DFS序
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2009 Solved: 1056[Submit][Sta ...
- [luogu P3787][新创无际夏日公开赛] 冰精冻西瓜 [树状数组][dfs序]
题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...
随机推荐
- uniGUI中Cookies使用中文汉字的方法(使用EncodeString函数编码)
uniGUI中Cookies使用中文汉字的方法(使用EncodeString函数编码) 在目前的UniGUI(ver:0.88)中使用UniApplication.Cookies.SetCooki ...
- 有关C++模板inline的高性能在lambda与function的体现
前两天在群里跟人讨论到写库时对于lambda和function的取舍,跑了写测试查了些资料后基本得出结论: 如果没有自由变量的情况下,一般不要用function. 如果有自由变量的话,C++中的lam ...
- k8s docker集群搭建
一.Kubernetes系列之介绍篇 •Kubernetes介绍 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器 ...
- 剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前
题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有的奇数位于数组的前半部分,偶数位于数组的后半部分. 解题思路:数组中维护两个指针,第一个指针初始化时候指向数组头部,第二个指针初 ...
- 设置win版vim启动项[利刃篇]
vim默认启动设置有时不太好,想改一下,但是又不像windows其他软件那样,界面设置后就生效,这里需要手动设置文件才可以,那就赶紧设置一下吧! 修改文件为 vim安装目录/_vimrc 文件,或者在 ...
- linux下把动态链接库加入环境变量的几种方式
一. 将网络SDK各动态库路径加入到LD_LIBRARY_PATH环境变量 1.在终端输入:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/XXX 只在当前终端起作用 ...
- C# datagridview分页功能
winform开发是或多或少都会接触datagridview控件,如果数据量大,那么必须使用分页功能,但是datagridview自身并没有分页,所以我们要自己实现.在网上搜了一些发现没有太适合自己的 ...
- Spring Boot + Spring Cloud 构建微服务系统(七):API服务网关(Zuul)
技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡,那我们的各种微服务又要如何提供给外部应用调用呢. 当然,因为是REST API接口,外部客户端直接调用各个微服务是没有问 ...
- netty源码解解析(4.0)-11 Channel NIO实现-概览
结构设计 Channel的NIO实现位于io.netty.channel.nio包和io.netty.channel.socket.nio包中,其中io.netty.channel.nio是抽象实 ...
- 查找第K小的数 BFPRT算法
出处 http://blog.csdn.net/adong76/article/details/10071297 BFPRT算法是解决从n个数中选择第k大或第k小的数这个经典问题的著名算法,但很多人并 ...