=-=抓住叶节点往上揪

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. Scala教程之:静态类型

    文章目录 泛类型 型变 协变 逆变 不变 类型上界 类型下界 内部类 抽象类型 复合类型 自类型 隐式参数 隐式转换 多态方法 类型推断 Scala是静态类型的,它拥有一个强大的类型系统,静态地强制以 ...

  2. Netty(七):EventLoop学习前导——Reactor模式

    了解Netty的人多少都会知道Netty的高性能的一个原因就是它是基于事件驱动的,而这一事件的原型就是Reactor模式. 所以在学习EventLoop前,很有必要先搞懂Reactor模式. 本文目录 ...

  3. 数学--数论--HDU 2104 丢手绢(离散数学 mod N+ 剩余类 生成元)+(最大公约数)

    The Children's Day has passed for some days .Has you remembered something happened at your childhood ...

  4. P4768 [NOI2018]归程(kruskal 重构树)

    洛谷P4768 [NOI2018]归程 LOJ#2718.「NOI2018」归程 用到 kruskal 重构树,所以先说这是个啥 显然,这和 kruskal 算法有关系 (废话 这个重构树是一个有点权 ...

  5. python-函数变量与方法公有、私有整理

    关于函数与方法的区别: 函数: def funname(): 括号里面可以有形参,也可以没有,为空 在函数里面的参数整理: 方法: def funcname(self): 括号里面必须有个self,因 ...

  6. php扩展开发之hello world

    最近在公司做的事情就是php扩展开发,虽然我只负责c++代码的编写,但是了解扩展开发的流程还是很有必要的. (本文介绍的是动态扩展,对静态扩展有兴趣的读者可自行google) php扩展开发环境搭建可 ...

  7. zigbee通用IO口小作业

    独立新建工程并编写.编译代码,实现按键控制流水灯运行,完成以下任务要求: [1]程序开始运行时,D4.D3.D6.D5灯全亮一会,然后全灭一会,开始进入流水灯. [2]流水灯的运行过程为:D4灯亮,其 ...

  8. Vular开发手记#1:设计并实现一个拼插式应用程序框架

    可视化编(rxeditor)辑告一段落,在知乎上发了一个问题,询问前景,虽然看好的不多,但是关注度还是有的,目前为止积累了21w流量,因为这个事,开心了好长一段时间.这一个月的时间,主要在设计制作Vu ...

  9. repo使用总结—从入门到入门

    文章目录 1 what's repo 2 官方文档 Repo 命令参考资料 help 帮助 init 初始化 sync 同步所有项目文件 upload 提交更改 diff download foral ...

  10. 如何构建一个arm64 AArch64的Ubuntu rootfs

    文章目录 1 下载文件创建rootfs文件夹 2 安装qemu-user-static搭建arm64模拟环境 3 chroot 到 模拟arm64的文件系统下 4 安装基础的软件包 5 系统基础的修改 ...