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. Centos系统安装InfluxDB

    概述安装influxDB时需要root用户或者管理员权限. 端口默认情况下,InfluxDB会使用如下的端口: * TCP8086端口是服务器监听端口,对HTTP API响应 * TCP8088端口是 ...

  2. go连接mysql

    package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysq ...

  3. 开发微信小程序——古龙小说阅读器

    概述 由于面试的关系接触了一下微信小程序,花了2晚上开发了一个带书签功能的古龙小说阅读器,并且已经提交审核等待发布.这篇博文记录了我的开发过程和对微信小程序的看法,供以后开发时参考,相信对其他人也有用 ...

  4. eclipse——JDK安装与环境变量配置步骤

    第一次接触eclipse的时候,让我自己安装jdk和配置环境变量,我是懵逼的,后来百度到找到了一个比较详细的引导,本人测试没问题,截图按步骤如下: JDK安装   步骤1: 步骤2: 配置环境变量 步 ...

  5. WCF绑定netTcpBinding寄宿到控制台应用程序

    契约 新建一个WCF服务类库项目,在其中添加两个WCF服务:GameService,PlayerService 代码如下: [ServiceContract] public interface IGa ...

  6. CentOS 配置SOCKS5代理服务

    SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全 通过yum安装 ...

  7. Spring 中初始化一个Bean对象时依赖其他Bean对象空指针异常

    1. Bean依赖关系 一个配置类的Bean,一个实例Bean: 实例Bean初始化时需要依赖配置类的Bean: 1.1 配置类Bean @ConfigurationProperties(prefix ...

  8. C语言中const关键字的用法

    关键字const用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变,我想一定有人有这样的疑问,C语言中不是有#define吗,干嘛还要用const呢,我想事物的存在一定有它自己的道理 ...

  9. Python内置类型(1)——真值测试

    python中任何对象都能直接进行真假值的测试,用于if或者while语句的条件判断,也可以做为布尔逻辑运算符的操作数 python中任何对象都能直接进行真假值的测试,而不需要额外的类型转换 这一点是 ...

  10. nginx如何实现高并发

    nginx如何实现高并发 简单来讲,就是异步,非阻塞,使用了epoll和大量的底层代码优化. 稍微详细一点展开的话,就是nginx的特殊进程模型和事件模型的设计. 进程模型 nginx采用一个mast ...