题意:

给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值。

从中选出若干条链,两两不相交,并且使得权值之和最大。

分析:

题解

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <string>
using namespace std;
#define REP(i, a, b) for(int i = a; i < b; i++)
#define PER(i, a, b) for(int i = b - 1; i >= a; i--)
#define SZ(a) ((int)a.size())
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(a) a.begin(), a.end()
typedef long long LL;
typedef pair<int, int> PII; const int maxn = 100000 + 10; int n, m;
vector<int> G[maxn], Q[maxn];
int u[maxn], v[maxn], w[maxn];
int l[maxn], r[maxn], dfs_clock;
int dp[maxn], sum[maxn]; int dep[maxn];
int anc[maxn][20]; void dfs(int u, int fa) {
l[u] = ++dfs_clock;
anc[u][0] = fa;
for(int i = 0; anc[u][i]; i++)
anc[u][i+1] = anc[anc[u][i]][i];
dep[u] = dep[fa] + 1;
for(int v : G[u]) if(v != fa) {
dfs(v, u);
}
r[u] = ++dfs_clock;
} int LCA(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
PER(i, 0, 20)
if(dep[anc[u][i]] >= dep[v]) u = anc[u][i];
if(u == v) return u;
PER(i, 0, 20) if(anc[u][i] != anc[v][i])
u = anc[u][i], v = anc[v][i];
return anc[u][0];
} int C[maxn << 1];
#define lowbit(x) (x&(-x))
void add(int x, int v) {
while(x <= n * 2) {
C[x] += v;
x += lowbit(x);
}
}
int query(int x) {
int ans = 0;
while(x) {
ans += C[x];
x -= lowbit(x);
}
return ans;
} void init() {
REP(i, 1, n + 1) G[i].clear(), Q[i].clear();
memset(anc, 0, sizeof(anc));
dfs_clock = 0;
memset(C, 0, sizeof(C));
memset(dp, 0, sizeof(dp));
memset(sum, 0, sizeof(sum));
} void upd(int& a, int b) { if(a < b) a = b; } void solve(int x) {
for(int y : G[x]) if(y != anc[x][0]) {
solve(y);
sum[x] += dp[y];
}
dp[x] = sum[x];
for(int q : Q[x]) {
upd(dp[x], sum[x] + query(l[u[q]]) + query(l[v[q]]) + w[q]);
}
add(l[x], sum[x] - dp[x]);
add(r[x], dp[x] - sum[x]);
} int main() {
int T; scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
init();
REP(i, 1, n) {
int u, v; scanf("%d%d", &u, &v);
G[u].PB(v);
G[v].PB(u);
}
dfs(1, 0);
REP(i, 0, m) {
scanf("%d%d%d", u + i, v + i, w + i);
int lca = LCA(u[i], v[i]);
Q[lca].PB(i);
}
solve(1);
printf("%d\n", dp[1]);
} return 0;
}

HDU 5293 Tree chain problem 树形DP的更多相关文章

  1. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  2. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  3. (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。

    Problem Description   Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...

  4. hdu5293 Tree chain problem 树形dp+线段树

    题目:pid=5293">http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最 ...

  5. codeforces 671D Roads in Yusland & hdu 5293 Tree chain problem

    dp dp优化 dfs序 线段树 算是一个套路.可以处理在树上取链的问题.

  6. HDU 5293 Tree chain problem

    树状数组 + dp 设$f_i$表示以$i$为根的子树中的能选取的最大和,$sum_x$表示$\sum_{f_y}$  ($y$是$x$的一个儿子),这样子我们把所有给出的链按照两点的$lca$分组, ...

  7. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  8. HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp

    传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...

  9. 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集

    [题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...

随机推荐

  1. appium (三)执行过程

      转自http://blog.csdn.net/Yejianyun1/article/details/56012470 appium界面运行过程: 1.启动一个http服务器:127.0.0.1:4 ...

  2. expres webpack es6 babel 构建多页系统开发架构

    开始写点什么... 只是一个思路........

  3. 详细讲解:通过composer安装TP5.1(Thinkphp5.1)

    现在TP5越来越火了,TP5也更新到了5.1版本,但是5.1以上版本只能通过composer来进行安装,那么这里贴出详细的步骤 前提:PHP版本必须要5.6以上 参考网址:http://www.thi ...

  4. ubuntu16.4安装 VirtualBox

    1) 从oracle官网下载virtual box安装包 2) 安装支持包 sudo apt-get install libqt5x11extras5 libsdl1.2debian 3) sudo ...

  5. jrtplib源码分析 第一篇 jthread的编译与分析

    第一篇 jthread的编译与分析 jrtplib代码依赖库jthread,因此先从jthread开始jrtplib的学习.首先从以下链接下载jthread的源代码http://research.ed ...

  6. S/4HANA for Customer Management里的搜索分页处理

    这篇文章的英文版我发在了SAP Community上:Paging Implementation in S/4HANA for Customer Management https://blogs.sa ...

  7. IOS GCD(线程的 串行、并发 基本使用)

    什么是GCD 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自 ...

  8. 【洛谷4815】[CCO2014] 狼人游戏(树形DP)

    点此看题面 大致题意: 已知有平民和狼人共\(n\)个,每个平民会指控和保护任何人,每个狼人只会指控平民.保护狼人.告诉你\(m\)对指控与保护的关系,求有\(k\)个狼人的方案总数. 树形\(DP\ ...

  9. 【转】Android开发学习笔记(一)——初识Android

    对于一名程序员来说,“自顶向下”虽然是一种最普通不过的分析问题和解决问题的方式,但其却是简单且较为有效的一种.所以,将其应用到Android的学习中来,不至于将自己的冲动演变为一种盲目和不知所措. 根 ...

  10. Python实现接口测试中的常见四种Post请求数据

    前情: 在日常的接口测试工作中,模拟接口请求通常有两种方法, 利用工具来模拟,比如fiddler,postman,poster,soapUI等 利用代码来模拟,使用到一些网络模块,比如HttpClie ...