【题目】

Tree chain problem

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
 
 
【题意】
  给一些数链,每个数链有权值,找最权值最大的互不相交数链集。
 
【分析】
  怎么说,其实不是很难。
  TreeDP,f[i]表示i的子树的答案,然后考虑i上面是否有链(如果有,只考虑i为lca的树链)
  

  有两种可能,第一种:第i个节点上不出现链,那么dp[i] = ∑(dp[k] | k为i的子节点);

第二种:第i个节点上出现链,如果选择加入这条链,那么dp[i] = w(链的权值) + ∑(dp[k] | k为链上的节点的子节点) = w + ∑(sum[k] | k为链上的节点 ) - ∑(dp[k] | k为链上的节点) 。sum[i]表示i节点的所有子节点的dp和,在 ∑(sum[k] | k为链上的节点 ) - ∑(dp[k] | k为链上的节点) 中减去的dp[k]会由它的父节点的sum补全。这样就得到了状态转移公式。

转自:http://blog.csdn.net/winddreams/article/details/47004187

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define Maxn 100010 struct node
{
int x,y,next;
}t[Maxn*];int len;
int first[Maxn]; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} int mymax(int x,int y) {return x>y?x:y;} int nx[Maxn],ny[Maxn],w[Maxn]; int dfn[Maxn],sm[Maxn],dep[Maxn],son[Maxn],fa[Maxn];
int cnt;
void dfs1(int x,int f)
{
dep[x]=dep[f]+;fa[x]=f;
sm[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
dfs1(y,x);
sm[x]+=sm[y];
if(sm[y]>sm[son[x]]) son[x]=y;
}
} int n,m;
int tp[Maxn];
void dfs2(int x,int f,int tpp)
{
dfn[x]=++cnt;tp[x]=tpp;
if(son[x]) dfs2(son[x],x,tpp);
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f&&t[i].y!=son[x])
dfs2(t[i].y,x,t[i].y);
} int c[Maxn];
vector<int > v[Maxn]; int add(int x,int y)
{
for(int i=x;i<=n;i+=i&(-i))
c[i]+=y;
} int query(int l,int r)
{
int ans=;
for(int i=r;i>=;i-=i&(-i))
ans+=c[i];
l--;
for(int i=l;i>=;i-=i&(-i))
ans-=c[i];
return ans;
} int gans(int x,int y,int p)
{
int ans=,tt;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) tt=x,x=y,y=tt;
if(p==) ans+=query(dfn[tp[x]],dfn[x]);
x=fa[tp[x]];
}
if(dep[x]<dep[y]) tt=x,x=y,y=tt;
if(p==)
{
ans+=query(dfn[y],dfn[x]);
return ans;
}
else return y;
} int sum[Maxn],g[Maxn],lca[Maxn];
void ffind(int x,int f)
{
sum[x]=g[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
ffind(t[i].y,x);
sum[x]+=g[t[i].y];
}
add(dfn[x],sum[x]);
g[x]=sum[x];
for(int i=;i<v[x].size();i++)
{
int now=gans(nx[v[x][i]],ny[v[x][i]],);
g[x]=mymax(g[x],now+w[v[x][i]]);
}
add(dfn[x],-g[x]);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
len=;
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
dep[]=;
memset(son,,sizeof(son));
dfs1(,);cnt=;
dfs2(,,);
for(int i=;i<=n;i++) v[i].clear();
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&nx[i],&ny[i],&w[i]);
lca[i]=gans(nx[i],ny[i],);
v[lca[i]].push_back(i);
}
memset(c,,sizeof(c));
ffind(,);
printf("%d\n",g[]);
}
return ;
}

2016-11-10 19:56:36

  

【HDU 5233】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

    题意: 给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值. 从中选出若干条链,两两不相交,并且使得权值之和最大. 分析: 题解 #include <cstdio> #incl ...

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

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

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

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

  6. HDU 5293 Tree chain problem

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

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

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

  8. hdu5293(2015多校1)--Tree chain problem(树状dp)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  9. Codeforces 791D Bear and Tree Jump(树形DP)

    题目链接 Bear and Tree Jumps 考虑树形DP.$c(i, j)$表示$i$最少加上多少后能被$j$整除. 在这里我们要算出所有$c(i, k)$的和. 其中$i$代表每个点对的距离, ...

随机推荐

  1. rndc: connect failed: 127.0.0.1#953: connection refused

    [root@localhost sbin]# ./named -v bind 9.5.1-p3-v3.0.9 问题现象: [root@localhost sbin]# ./rndc flush -p ...

  2. Java内存模型浅析

    JVM在执行java程序时会将它所管理的内存划分成若干个不同的数据区域.如图所示: 其中方法区和堆是所有线程共享的数据区,其他区域则是线程隔离的数据区. 这些区域的功能各有不同: 程序计数器:可以理解 ...

  3. Unity3D NGUI学习(一)血条

    这次来讲讲Unity3D NGUI这个插件的学习,这个插件是收费的,不过去网上可以下载得很多可用版本.用来做用户的交互UI,学习起来比较简单 第一步,导入NGUI包 http://pan.baidu. ...

  4. Help View修复

    好吧,手贱把ProgramData里关于Help View的某些数据删除了 (在任何情况下都不要删除此文件夹中的任何数据).即使卸载后重新安装也出现错误,可以参考的http://social.msdn ...

  5. c编程:用户输入一个数值n,打印出出1到n之间的所有质数

    #include <stdio.h> int func(int i ) { //定义一个变量temp=2,当主函数引入的数大于temp时进入for循环.当它在比自己小的数中找到一个能背整除 ...

  6. 记:mysql 连接超时解决办法

    错误描述:Timeout in IO operation 原连接字符串为:Server=182.180.50.118;port=3306;Database=test;Uid=root;Pwd=123; ...

  7. 关于Spring AOP和IOC的一些总结

    Spring官方网站:https://spring.io/ 最早对象的创建是有new关键字,但是如果产生的类比较繁多或者复杂,就用工厂代替new关键字,但是工厂的控制能力有限,譬如对产生对象的生命周期 ...

  8. 12_复杂查询01_Mapper代理实现

    [工程截图] [代码实现] [user.java] package com.Higgin.Mybatis.po; import java.util.Date; public class User { ...

  9. jquery放大镜插件与样式

    这是放大镜插件链接,我已经上传到我博客http://files.cnblogs.com/valiant1882331/%E6%94%BE%E5%A4%A7%E9%95%9C%E6%8F%92%E4%B ...

  10. setInterval和setTimeout定时器

    1,文本框自增(重零开始)每隔一秒递增1 <input type="text" name="name" value="0" id=&q ...