题目:

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

题解:

见:http://blog.csdn.net/cdsszjj/article/details/78249687

很好的一道树形dp题··感觉以后要是考到关于根节点到其所在子树中某一点所形成的链的相关题都可以这样考虑·····

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2e5+;
struct node
{
int x,y,val;
}line[N];
vector<int>root[N];
inline int R()
{
char c;int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar()) f=(f<<)+(f<<)+c-'';
return f;
}
int T,fst[N],go[N],nxt[N],tot,n,m;
int tree[N],g[N][],deep[N],f[N],sum[N],l[N],r[N],cnt;
inline void comb(int a,int b)
{
nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b;
nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a;
}
inline void dfs(int u,int fa)
{
l[u]=++cnt;
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];if(v==fa) continue;
deep[v]=deep[u]+,g[v][]=u;dfs(v,u);
}
r[u]=cnt+;
}
inline int get(int a,int b)
{
int i,j;
if(deep[a]<deep[b]) swap(a,b);
for(i=;(<<i)<=deep[a];i++);i--;
for(j=i;j>=;j--)
if(deep[a]-(<<j)>=deep[b]) a=g[a][j];
if(a==b) return a;
for(i=;i>=;i--)
if(g[a][i]!=g[b][i]) a=g[a][i],b=g[b][i];
return g[a][];
}
inline int query(int pos)
{
int temp=;
for(int i=pos;i;i-=(i&(-i))) temp+=tree[i];
return temp;
}
inline void insert(int pos,int x)
{
for(int i=pos;i<=n+;i+=(i&(-i))) tree[i]+=x;
}
inline void dp(int u,int fa)
{
sum[u]=,f[u]=;
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];
if(v==fa) continue;
dp(v,u);sum[u]+=f[v];
}
f[u]=sum[u];
for(int i=;i<root[u].size();i++)
{
node temp=line[root[u][i]];
int a=temp.x,b=temp.y,c=temp.val;
f[u]=max(f[u],sum[u]+query(l[a])+query(l[b])+c);
}
insert(l[u],sum[u]-f[u]);
insert(r[u],f[u]-sum[u]);
}
inline void pre()
{
memset(fst,,sizeof(fst));tot=,cnt=;
memset(g,,sizeof(g));memset(tree,,sizeof(tree));
for(int i=;i<=n;i++) root[i].clear();
}
int main()
{
//freopen("a.in","r",stdin);
T=R();
while(T--)
{
n=R(),m=R();int a,b,c;
pre();
for(int i=;i<n;i++) a=R(),b=R(),comb(a,b);
dfs(,);
for(int i=;i<=;i++)
for(int j=;j<=n;j++) g[j][i]=g[g[j][i-]][i-];
for(int i=;i<=m;i++)
{
a=R(),b=R(),c=R();
int lca=get(a,b);
root[lca].push_back(i);
line[i].x=a,line[i].y=b,line[i].val=c;
}
dp(,);
cout<<f[]<<endl;
}
return ;
}
 

刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)的更多相关文章

  1. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

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

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

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

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

  4. hdu 3887 Counting Offspring dfs序+树状数组

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. hdu 5877 Weak Pair dfs序+树状数组+离散化

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Prob ...

  6. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  7. POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)

    http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...

  8. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  9. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

随机推荐

  1. groupdel - Delete a group

    总览 SYNOPSIS groupdel group 描述 DESCRIPTION groupdel 命令会修改系统帐号档,会删除所有指定群组的信息 . 群组名须存在. 你须手动确认一下所有的档案系统 ...

  2. 剑指offer38 数字在排序数组中出现的次数

    这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...

  3. Kafka 完全分布式集群环境搭建

    思路: 先在主机s1上安装配置,然后远程复制到其它两台主机s2.s3上, 并分别修改配置文件server.properties中的broker.id属性. 1. 搭建前准备 示例共三台主机,主机IP映 ...

  4. JavaScript深入浅出第2课:函数是一等公民是什么意思呢?

    摘要: 听起来很炫酷的一等公民是啥? <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函 ...

  5. python3  循环输出当前时间。

    题目 暂停一秒输出(使用 time 模块的 sleep() 函数).循环输出当前时间. 代码: import time while True: time.sleep(1) print(time.str ...

  6. OpenCV中的图像形态学转换

    两个基本的形态学操作是腐蚀和膨胀.他们的变化构成了开运算,闭运算,梯度等.下面以这张图为例 1.腐蚀 这个操作会把前景物体的边界腐蚀掉. import cv2 import numpy as np i ...

  7. Linux: 正则表达式

    正则表达式:正规的表示法,常规的表示法(Regular Expression)正则表达式使用单个字符串来描述,匹配一系列的符合某个句发规则的字符串. 1)命令格式; grep  [正则] 字符串 文件 ...

  8. [转] sublime插件

    Sublime Text 系列 Sublime Text:学习资源篇 Sublime插件:增强篇 Sublime插件:Markdown篇 Sublime插件:C语言篇 Sublime插件:主题篇 Su ...

  9. UTV - URL Tag Validation

    What`s UTV 1.URL Tag Validation 2.Special format of URL for preventing unauthorized usage and access ...

  10. 和为s的两个数字 【微软面试100题 第十四题】

    题目要求: 输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. 例如输入数组{1,2,4,7,11,15}和数字15.由于4+1 ...