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 ...
随机推荐
- java之 惰性初始化
class Soap { private String s; Soap(){ System.out.println("Soap()"); s="Constructed&q ...
- PL/SQL登录Oracle18数据库:ORA-12154:TNS无法解析指定的连接标识符
PL/SQL登录Oracle18数据库出现ORA-12154:TNS无法解析指定的连接标识符解决以下问题:首先更改Oracle客户端的tnsnames.ora,我的路径是:D:\OracleSQL\n ...
- 标准库模块time,datetime
在Python中,通常有这几种方式来表示时间: 1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素. 由于Python的time模块实现主要调用C库,所以各个平台可能有所 ...
- nginx平滑升级、在线添加模块(tengine 动态加载模块)
http://www.orzace.com/how-to-upgrade-nginx/ 下面是nginx替换成tengine再加上lua 模块,(tengine-2.0.1版本暂时无法动态加载lua模 ...
- 数学--数论--随机算法--Pollard Rho 大数分解算法 (带输出版本)
RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试. 操作流程 首先,我们先用MillerRabinMille ...
- Java自动装箱与缓存
自动装箱与缓存 现象 有以下代码: 1 public class Main { 2 public static void main(String[] args) { 3 Integer i1 = 12 ...
- ssrf爆破mysql
php ssrf 代码<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $_GET['url']); #curl_setopt($ch ...
- Vue + Element-ui实现后台管理系统(1) --- 总述
总述 一.项目效果 整体效果 登陆页 后台首页 用户管理页 说明 这里所有的数据都不是直接通过后端获取的, 而是通过Mock这个工具来模拟后端返回的接口数据. 附上github地址: mall-ma ...
- 常见的GAN网络的相关原理及推导
常见的GAN网络的相关原理及推导 在上一篇中我们给大家介绍了GAN的相关原理和推导,GAN是VAE的后一半,再加上一个鉴别网络.这样而导致了完全不同的训练方式. GAN,生成对抗网络,主要有两部分构成 ...
- Nginx下的location,upstream,rewrite 和 proxy_pass使用总计大全
一 . location: 顾名思义-->地址,也叫路由. nginx服务器非常核心的配置,一般nginx运维人员在修改nginx配置时,大部分也是围绕着location这个配置进行修改. 下面 ...