=-=抓住叶节点往上揪

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

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")

#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的更多相关文章

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

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

  2. Codeforces 856D - Masha and Cactus(树链剖分优化 dp)

    题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...

  3. [NOIP2018提高组] 保卫王国 (树链剖分+动态DP)

    题面 题目链接-Luogu 题目链接-Loj(要加Freopen) 题解 什么是动态DP? OneInDark:你不需要知道这么多,你只需要知道是利用了广义矩阵乘法就够了! 广义矩乘 广义矩阵乘法,简 ...

  4. BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)

    题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...

  5. BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP

    题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...

  6. bzoj4543 [POI2014]Hotel加强版 长链剖分+树形DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4543 题解 这道题的弱化版 bzoj3522 [POI2014]Hotel 的做法有好几种吧. ...

  7. 【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)

    前言 其实我只是为了过掉模板而写的ddp,实际应用被吊着锤 Solution 并不想写详细的过程 一句话过程:将子树中轻儿子的贡献挂到这个点上面来 详细版:(引用yyb) 总结一下的话,大致的过程是这 ...

  8. 【BZOJ4712】洪水 树链剖分优化DP+线段树

    [BZOJ4712]洪水 Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到山顶放了格水.于是小A面前出现了一个瀑布.作为 ...

  9. CF1111E Tree 树链剖分,DP

    CF1111E Tree 过年了,洛咕还没爬这次的题,先放个CF的链接吧. 补个LG传送门. 对于每个询问点\(x\),设它的祖先即不能和它放在同一个集合中的点的个数为\(f[x]\),设\(dp[i ...

随机推荐

  1. Vue项目开发流程(自用)

    一.配置开发环境 1.1 安装Node.js npm集成在Node中,检查是否安装完成:node -v 1.2 安装cnpm(淘宝镜像) npm install -g cnpm,检查安装是否完成:cn ...

  2. CentOS 6.5下通过yum安装MongoDB记录

    安装MongoDB 1.创建repo vi /etc/yum.repos.d/mongodb-org-3.6.repo   [mongodb-org-3.6]   name=MongoDB Repos ...

  3. 解决vue页面刷新或者后退参数丢失的问题

    原文链接: 点我 在商城类的项目中,会经常遇到列表数据筛选查询的情景,当要打开某一项的详情页或者暂时离开列表页,再返回(后退时),选择的筛选条件会全部丢失,辛辛苦苦选择好的条件全没了,还得重新选择,如 ...

  4. CF--思维练习--CodeForces - 221C-H - Little Elephant and Problem (思维)

    ACM思维题训练集合 The Little Elephant has got a problem - somebody has been touching his sorted by non-decr ...

  5. Jmeter 后置处理器

    1.JSON Extractor Json extractor 后置处理器用在返回格式为 Json 的 HTTP 请求中,用来获取返回的 Json 中的某个值.并保存成变量供后面的请求进行调用或断言等 ...

  6. windows中配置安装mysql数据库

    MySql 是一种免费的关系型数据库,相较于 MsSqlServer 和 Oracle 比较轻量化,安装也很简单,而且免费不需要的版权费用,个人认为一般的小项目采用还是比较合适的,当然也有部分数据量很 ...

  7. Javajdk的安装

    初次接触Java,这是我真正接触的第一门编程语言,在学习它之前,我曾看过一些c语言的书籍,可是并没有进行代码实现,在上手了Java后,并不懂的如何让代码运行,通过一点一点的学习和积累,今天记录下Jav ...

  8. 李婷华 201771010113 《面向对象程序设计(java)》第一周学习总结

    第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com 薄荷蓝莓 程序设计评测:https://pintia.cn/ 1957877441@q ...

  9. 第十一章:Python高级编程-协程和异步IO

    第十一章:Python高级编程-协程和异步IO Python3高级核心技术97讲 笔记 目录 第十一章:Python高级编程-协程和异步IO 11.1 并发.并行.同步.异步.阻塞.非阻塞 11.2 ...

  10. Day_11【集合】扩展案例3_打印最高分的学员姓名、年龄、成绩,打印10个学生的总成绩和平均分,打印不及格的学员信息及数量

    分析以下需求,并用代码实现 1.定义Student类 属性: 姓名:String name 年龄:int age 成绩:int score 行为: 空参构造方法 有参构造方法 set和get方法 to ...