Annoying problem

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5293

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

题意

给你一棵树,树上有n个点。

然后给你m条链,然后让你选择一些不相交的链,使得权值和最大。(每条链都有权值)

题解:

树形dp+dfs序+树状数组

首先想到的一点用dp[i]表示以i为根的子树最大值。

所给你的链只用考虑在lca这个点拿。

一个辅助数组sum[i]表示i点儿子的所有dp值的和。

然后dp方程就很显然了:

1.如果i点不拿任何链,那么dp[i]=sum[i]

2.如果i点拿了一条链,那么dp[i]=sum[i]+dp[v]+w,dp[v]是以那条链中的某个节点为父亲的点的dp值。

比较显然的发现dp[v] = sum[k] - dp[k],k即为那条链上的点。

然后这个东西按照dfs序去维护一个树状数组就好了。

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
const int maxm = 25;
struct node
{
int l,r,w;
node(int l=0,int r=0,int w=0):l(l),r(r),w(w){}
};
vector<int>E[maxn];
vector<node>query[maxn];
int n,m,x,y,z,dp[maxn],in[maxn],out[maxn],deep[maxn],lca[maxn][maxm],cnt,sum[maxn];
struct Bit
{
int a[maxn];
void init(){memset(a,0,sizeof(a));}
int lowbit(int x){return x&(-x);}
void update(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit(i))
a[i]+=v;
}
int get(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=a[i];
return ans;
}
}T;
void init()
{
cnt=1;
for(int i=0;i<maxn;i++)
E[i].clear(),query[i].clear();
T.init();
memset(deep,0,sizeof(deep));
memset(lca,0,sizeof(lca));
memset(dp,0,sizeof(dp));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(sum,0,sizeof(sum));
}
void dfs(int x,int p)
{
in[x]=cnt++;
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(v==p)continue;
deep[v]=deep[x]+1;
lca[v][0]=x;
for(int j=1;j<maxm;j++)
{
int fa = lca[v][j-1];
if(fa==0)continue;
lca[v][j]=lca[fa][j-1];
}
dfs(v,x);
}
out[x]=cnt++;
}
int up(int x,int d)
{
for(int i=maxm-1;i>=0;i--)
{
if(d<(1<<i))continue;
x=lca[x][i];
d-=(1<<i);
}
return x;
}
int Lca(int x,int y)
{
if(deep[x]>deep[y])swap(x,y);
y=up(y,deep[y]-deep[x]);
if(x==y)return x;
for(int i=maxm-1;i>=0;i--)
{
if(lca[x][i]!=lca[y][i])
x=lca[x][i],y=lca[y][i];
}
return lca[x][0];
}
void dfs2(int x,int fa)
{
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(v==fa)continue;
dfs2(v,x);
sum[x]+=dp[v];
}
dp[x]=sum[x];
for(int i=0;i<query[x].size();i++)
{
int l=query[x][i].l;
int r=query[x][i].r;
int w=query[x][i].w;
dp[x]=max(dp[x],sum[x]+T.get(in[r])+T.get(in[l])+w);
}
T.update(in[x],sum[x]-dp[x]),T.update(out[x],dp[x]-sum[x]);
}
void solve()
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
E[x].push_back(y);
E[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
query[Lca(x,y)].push_back(node(x,y,z));
}
dfs2(1,0);
cout<<dp[1]<<endl;
}
int main()
{
int t;scanf("%d",&t);
while(t--)solve();
return 0;
}

HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca的更多相关文章

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

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

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

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

  3. 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)

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

  4. 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 ...

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

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

  6. POJ 2763"Housewife Wind"(DFS序+树状数组+LCA)

    传送门 •题意 一对夫妇居住在 xx村庄,给村庄有 $n$ 个小屋: 这 $n$ 个小屋之间有双向可达的道路,不会出现环,即所构成的图是个树: 从 $a_i$ 小屋到 $b_i$ 小屋需要花费 $w_ ...

  7. BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )

    虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...

  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. flask插件系列之flask_session会话机制

    flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制. 配置参数详解 SESSION_COOKIE_NAME 设置返回给客户端的c ...

  2. mysqldump 逻辑备份的正确方法【转】

    1. 利用mysqldump进行逻辑备份 1)全逻辑备份: mysqldump -uxxx -p --flush-logs --delete-master-logs --all-databases & ...

  3. python3.6升级及setuptools、pip安装

    升级python3.6 1.打开官网www.python.org,找到最新3.6.3版本,复制下载链接 2.创建/app目录,wget下载到该目录下,编译安装 mkdir /app cd /app w ...

  4. 转载:Logistic回归原理及公式推导

    转载自:AriesSurfer 原文见 http://blog.csdn.NET/acdreamers/article/details/27365941 Logistic回归为概率型非线性回归模型,是 ...

  5. Effective STL 阅读笔记: Item 4 ~ 5: Call empty instead of checking size() against zero.

    Table of Contents 1 Item 4: Call empty instead of checking size() against zero 2 Item 5: Prefer rang ...

  6. [ JS 进阶 ] Repaint 、Reflow 的基本认识和优化

    你是不是经常听师兄或一些前端前辈说不能用CSS通配符 *,CSS选择器层叠不能超过三层,CSS尽量使用类选择器,书写HTML少使用table,结构要尽量简单-DOM树要小....等这些忠告,以前我就大 ...

  7. html学习-css

    1.css初识 css 中文解释:层叠样式表,把html比作骨骼的话,css就是衣服,他的外在都能通过css来修饰,js则是肌肉,能使html动起来.产生用户交互... 1.1css样式表类型 css ...

  8. LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)

    本文转自:原文链接  http://www.cnblogs.com/doseoer/p/4367536.html 网上我看到有很多相关的文章都是简述这个问题的,但毕竟因为LINUX版本众多,很多LIU ...

  9. PHP 标准AES加密算法类

    分享一个标准PHP的AES加密算法类,其中mcrypt_get_block_size('rijndael-128', 'ecb');,如果在不明白原理的情况下比较容易搞错,可以通过mcrypt_lis ...

  10. [loj6039]「雅礼集训 2017 Day5」珠宝 dp+决策单调性+分治

    https://loj.ac/problem/6039 我们设dp[i][j]表示考虑所有价值小于等于i的物品,带了j块钱的最大吸引力. 对于ci相同的物品,我们一定是从大到小选k个物品,又发现最大的 ...