HDU5293 树链剖分+树形DP
=-=抓住叶节点往上揪
Tree chain problem
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1752 Accepted Submission(s): 561
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
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.
A single integer, the maximum number of paths.
7 3
1 2
1 3
2 4
2 5
3 6
3 7
2 3 4
4 5 3
6 7 3
Stack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+88;
int fa[maxn],dep[maxn],size[maxn],pos[maxn],bl[maxn],head[maxn];
int sum[maxn];
int dp[maxn],su[maxn],n,m;
vector<int>G[maxn];
struct node{
int to,next;
}edge[maxn<<1];
struct cst{
int x,y,z;
}road[maxn];
int tot,sz;
void init(){
tot=sz=0;
memset(sum,0,sizeof(sum));
memset(head,-1,sizeof(head));
for(int i=1;i<=n;++i) G[i].clear();
}
void add(int u,int v) {
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void sadd(int u,int val) {
for( ; u<=n;u+=u&(-u))
sum[u]+=val;
}
int getsum(int u) {
int ret=0;
for(;u;u-=u&(-u))
ret+=sum[u];
return ret;
}
void dfs1(int x){
size[x]=1;
for(int i=head[x];i+1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[x]) continue;
fa[v]=x;
dep[v]=dep[x]+1;
dfs1(v);
size[v]+=size[x];
}
}
void dfs2(int x,int chain)
{
bl[x]=chain;
pos[x]=++sz;
int k=0;
for(int i=head[x];i+1;i=edge[i].next){
int v=edge[i].to;
if(dep[v]>dep[x]&&size[v]>size[k])
k=v;
}
if(!k) return;
dfs2(k,chain);
for(int i=head[x];i+1;i=edge[i].next)
if(dep[edge[i].to]>dep[x]&&edge[i].to!=k)
dfs2(edge[i].to,edge[i].to);
}
int LCA(int x,int y){
while(bl[x]!=bl[y]) {
if(dep[bl[x]]<dep[bl[y]]) swap(x,y);
x=fa[bl[x]];
}
if(pos[x]>pos[y]) swap(x,y);
return x;
}
int query(int x,int y){
int ret=0;
while(bl[x]!=bl[y]){
if(dep[bl[x]]<dep[bl[y]]) swap(x,y);
ret+=getsum(pos[x])-getsum(pos[bl[x]]-1);
x=fa[bl[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret+=getsum(pos[y])-getsum(pos[x]-1);
return ret;
}
void solve(int u){
su[u]=0;
for(int i=head[u];i+1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u]) continue;
solve(v);
su[u]+=dp[v];
}
dp[u]=su[u];
for(int i=0;i<(int)G[u].size();++i){
int v=G[u][i];
dp[u]=max(dp[u],query(road[v].x,road[v].y)+su[u]+road[v].z);
}
sadd(pos[u],su[u]-dp[u]);
}
int main(){
int t,u,v;
for(scanf("%d",&t);t--;){
scanf("%d%d",&n,&m);
init();
for(int i=1;i<n;++i){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1);
dfs2(1,1);
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&road[i].x,&road[i].y,&road[i].z);
G[LCA(road[i].x,road[i].y)].push_back(i);
}
solve(1);
printf("%d\n",dp[1]);
}
}
HDU5293 树链剖分+树形DP的更多相关文章
- (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。
Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...
- Codeforces 856D - Masha and Cactus(树链剖分优化 dp)
题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...
- [NOIP2018提高组] 保卫王国 (树链剖分+动态DP)
题面 题目链接-Luogu 题目链接-Loj(要加Freopen) 题解 什么是动态DP? OneInDark:你不需要知道这么多,你只需要知道是利用了广义矩阵乘法就够了! 广义矩乘 广义矩阵乘法,简 ...
- BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)
题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...
- BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP
题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...
- bzoj4543 [POI2014]Hotel加强版 长链剖分+树形DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4543 题解 这道题的弱化版 bzoj3522 [POI2014]Hotel 的做法有好几种吧. ...
- 【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)
前言 其实我只是为了过掉模板而写的ddp,实际应用被吊着锤 Solution 并不想写详细的过程 一句话过程:将子树中轻儿子的贡献挂到这个点上面来 详细版:(引用yyb) 总结一下的话,大致的过程是这 ...
- 【BZOJ4712】洪水 树链剖分优化DP+线段树
[BZOJ4712]洪水 Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到山顶放了格水.于是小A面前出现了一个瀑布.作为 ...
- CF1111E Tree 树链剖分,DP
CF1111E Tree 过年了,洛咕还没爬这次的题,先放个CF的链接吧. 补个LG传送门. 对于每个询问点\(x\),设它的祖先即不能和它放在同一个集合中的点的个数为\(f[x]\),设\(dp[i ...
随机推荐
- 删除集群mds
2019独角兽企业重金招聘Python工程师标准>>> 删除cephfs文件系统步骤: 1.停掉服务端mds: #systemctl stop {mds_service} 2.将md ...
- AngularJS学习1-基础知识
Angular并不是适合任何应用的开发,Angular考虑的是构建CRUD应用 但是目前好像也只是用到了angular的一些指令,数据绑定,mvc,http服务而已..... 以前传统的做法就是,通过 ...
- linux之centos安装jdk以及nginx详细过程
一.安装jdk 1:首先下载jdk到本地,然后通过git 上传到linux服务器上 2:进入目录usr,并创建目录java,将jdk的压缩文件移动到该目录下 cd /usr mkdir java mv ...
- Jmeter 数据库测试参数化
1.JDBC Request 参数化 方法一.Jmeter 参数化,在 sql query 中使用变量 Jmeter 参数化,使用 csv 参数化 sql query 中使用 ${变量名} 引用 方法 ...
- andorid jar/库源码解析之Dagger/Dagger2
目录:andorid jar/库源码解析 Dagger.Dagger2: 作用: 1.用于解耦Activity和业务逻辑 2.在使用业务的时候,不需要重复编写new代码. 3.当业务变化的时候,不需要 ...
- Spring AOP概述
一.AOP的基本概念: 首先先给出一段比较专业的术语: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的 ...
- 线段树 区间合并 F - Sequence operation
F - Sequence operation 题解:这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,这个有两个地方要注意一下,一 ...
- 用VirtualBox代替VMWare安装Ubuntu系统图文教程总结
文章目录 为什么使用VirtualBox,而不是VMWare? 图文教程 安装VirtualBox 下载Ubuntu镜像 新建虚拟机 安装Ubuntu系统 总结 为什么使用VirtualBox,而不是 ...
- 帝国cms列表页内容简介字段smalltext去除里面html格式代码 设置方法
帝国cms列表页内容简介字段smalltext去除里面html格式代码帝国cms列表页调用内容简介出现html代码怎么办 近来在用帝国cms的时候,发现一个问题,在列表页调用产品简介的时候出现了这种h ...
- 上位机开发之三菱Q系列PLC通信实践
经常关注我们公众号或者公开课的学员(如果还没有关注的话,左上角点击一波关注)应该知道,我们会经常使用西门子PLC,其实对于其他品牌的PLC,我们都会讲到,包括三菱.欧姆龙.基恩士.松下及国产台达.信捷 ...