题意:

给出一棵\(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. Struts2_BBS2009小实战

    Struts2_BBS2009准备:链接: http://pan.baidu.com/s/1nvTZz9R 密码: 875a ext3.0_直接部署运行:链接: http://pan.baidu.co ...

  2. Linux远程桌面(二)

    上一篇远程桌面采用的独立服务配置不适用于过多用户,这一篇采用超级Internet服务器搭建vnc服务可以解决多用户问题.  vnc之xinetd服务搭建配置 Linux远程桌面(一):vnc之独立服务 ...

  3. PHP : 封装跳转函数,实现三个页面的跳转

    具体实现:有a,b两个页面,一个跳转页面c,在a执行完后先进行c页面的提示,再跳转到b 1.文件设计: 2.c页面封装方法内容(function.php): a页面内容(a.html): a页面的后台 ...

  4. 安卓NDK流程

    定义wrap类,声明native函数,加载库 package com.ndk.hello; public class Classs { public native String say_hello() ...

  5. 幻灯片的JQuqey的制作效果,只要几行代码

    使用jquery.KinSlideshow.js就可以很轻松的实现幻灯片效果   htm代码: [html]   <div id="focusNews" style=&quo ...

  6. 富文本 文字图片点击,(TextView)

    textview上的富文本支持 文字,图片的点击事件 - (void)protocolIsSelect:(BOOL)select { NSMutableAttributedString *attrib ...

  7. 使用node.js + socket.io + redis实现基本的聊天室场景

    在这篇文章Redis数据库及其基本操作中介绍了Redis及redis-cli的基本操作. 其中的publish-subscribe机制应用比较广泛, 那么接下来使用nodejs来实现该机制. 本文是对 ...

  8. while counter<10:

    [root@chenbj test]# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat ...

  9. matlab的figure窗口命名为中文

    figure('NumberTitle', 'off', 'Name', '我的窗口名字');

  10. CDH4.5.0源代码编译

    Unable to load native-hadoop library for your platform解决 安装maven 1 cmake-2.8.12.1.tar.gz cd cmake-2. ...