题意是给了 n 个点的树,会有m条链条 链接两个点,计算出他们没有公共点的最大价值,  公共点时这样计算的只要在他们 lca 这条链上有公共点的就说明他们相交

dp[i]为这个点包含的子树所能得到的最大价值

sum[i]表示这个点没有选择经过i这个点链条的总价值

两种选择

这个点没有被选择

dp[i]=sum[i]=sigma(dp[k])k为i的子树

选择了某个链

假设这条链 为(tyuijk)

那么dp[i]=(sum[i]-dp[u]-dp[j])+(sum[j]-dp[k])+dp[k] +(sum[u]-dp[y])+(sum[y]-dp[t])+sum[t];

整理后发现 dp[i]=sum[i] +(sum[j]-dp[j])+(sum[k]-dp[k])+(sum[u]-dp[u])+(sum[y]-dp[y])+(sum[t]-dp[t]);

使用lca计算出每条链的最近公共祖先,在这个最近公共祖先上判断是否使用这条链,还有我们可以使用时间戳加树状数组来求得sum和dp

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=+;
int to[maxn*],nx[maxn*],H[maxn*],numofedg,timoflook;
int fa[maxn][],first[maxn],last[maxn],depth[maxn];
void addedg(int u, int v)
{
numofedg++; to[numofedg]=v; nx[numofedg]=H[u]; H[u]=numofedg;
numofedg++; to[numofedg]=u; nx[numofedg]=H[v]; H[v]=numofedg;
}
void dfs(int cur, int per, int dep)
{
first[cur]=++timoflook;
depth[cur]=dep;
fa[cur][]=per;
for(int i=; i<; i++)
{
fa[cur][i]=fa[ fa[cur][i-] ][ i- ];
}
for(int i=H[cur]; i; i=nx[i])
{
if(to[i]==per)continue;
dfs(to[i],cur,dep+);
}
last[cur]=++timoflook;
}
int getlca(int u,int v)
{
if(depth[u]<depth[v])swap(u,v);
for(int i=; i>=; i--)
{
if(depth[fa[u][i]]>=depth[v])
u=fa[u][i];
if(u==v)return u;
}
for(int i=; i>=; i--)
{
if(fa[u][i]!=fa[v][i])
{
u=fa[u][i];
v=fa[v][i];
}
}
return fa[u][];
}
struct Edg
{
int u,v,lca,val;
}P[maxn];
vector<int>E[maxn];
int dp[maxn],sum[maxn],CS[maxn*],CD[maxn*];
int lowbit(int x)
{
return x&-x;
}
void add(int x, int d, int *C)
{
while(x<=timoflook)
{
C[x]+=d;
x+=lowbit(x);
}
}
int getsum(int x, int *C)
{
int ret=;
while(x>)
{
ret+=C[x];
x-=lowbit(x);
}
return ret;
}
void solve(int cur, int per)
{
dp[cur]=sum[cur]=;
for(int i=H[cur]; i; i=nx[i])
{
if(to[i]==per)continue;
solve(to[i],cur);
sum[cur]+=dp[to[i]];
}
dp[cur]=sum[cur];
for(int i=; i<E[cur].size(); i++)
{
int id=E[cur][i];
int u=P[id].u;
int v=P[id].v;
int t1=getsum(first[u],CS);
int t2=getsum(first[v],CS);
int t3=getsum(first[u],CD);
int t4=getsum(first[v],CD);
int tmp=t1+t2-t3-t4;
dp[cur]=max(dp[cur],tmp+P[id].val+sum[cur]);
}
add(first[cur],sum[cur],CS);
add(last[cur],-sum[cur],CS);
add(first[cur],dp[cur],CD);
add(last[cur],-dp[cur],CD); }
int main()
{
int cas;
scanf("%d",&cas);
for(int cc=; cc<=cas; cc++)
{
int n,m;
timoflook=numofedg=;
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
{
CS[i*]=CS[i*+]=CD[i*]=CD[i*+]=;
H[i]=;E[i].clear(); } for(int i=; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedg(u,v);
}
fa[][]=;
dfs(,,);
for(int i=; i<m; i++)
{
scanf("%d%d%d",&P[i].u,&P[i].v,&P[i].val);
P[i].lca=getlca(P[i].u,P[i].v);
E[P[i].lca].push_back(i);
}
solve(,-);
printf("%d\n",dp[]);
}
return ;
}

hdu5293 lca+dp+树状数组+时间戳的更多相关文章

  1. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  2. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

  3. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  4. 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...

  5. POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权

    题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作: 0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val   把第 x 条边的权值改为 ...

  6. 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...

  7. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

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

  8. UESTC 912 树上的距离 --LCA+RMQ+树状数组

    1.易知,树上两点的距离dis[u][v] = D[u]+D[v]-2*D[lca(u,v)] (D为节点到根节点的距离) 2.某条边<u,v>权值一旦改变,将会影响所有以v为根的子树上的 ...

  9. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

随机推荐

  1. 20165225《Java程序设计》第六周学习总结

    20165225<Java程序设计>第六周学习总结 1.视频与课本中的学习: - 第八章学习总结 String类 String对象(常量,对象) 字符串并置(结果仍是常量) 常用方法 le ...

  2. CF720A Closing ceremony 贪心

    正解:贪心 解题报告: 传送门! 先考虑如果只有一列怎么搞?那就肯定是尽量走到最远的地方 然后用点儿类似的思想,现在考虑有两列的情况QAQ 为了方便表述,这里给每个位置两个值,a表示离一号入口的距离, ...

  3. 那些年读过的书《Java并发编程实战》一、构建线程安全类和并发应用程序的基础

    1.线程安全的本质和线程安全的定义 (1)线程安全的本质 并发环境中,当多个线程同时操作对象状态时,如果没有统一的状态访问同步或者协同机制,不同的线程调度方式和不同的线程执行次序就会产生不同的不正确的 ...

  4. 3.0-uC/OS-III简介(操作系统结构)

    1.OS-III是一个第 3代的系统内核,支持现代的实时内核所期待的大部分功能. 例如资源管理, 同步, 任务间的通信等等.然而, uC/OS-III提供的特色功能在其它的实时内核中是找不到的, 比如 ...

  5. mysql 数据表操作 目录

    mysql 数据表操作 存储引擎介绍 mysql 使用存储引擎 mysql 数据表的增删改查 mysql 数据类型 mysql 约束条件

  6. strlen函数细节

    strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值. 原型: ...

  7. golang 中的 sizeof 以及 golang中的 union

    golang 中的 sizeof: 1: int(unsafe.Sizeof(uint32(0))) 2: int(reflect.TypeOf(uint32(0)).Size()) golang中的 ...

  8. Centos7安装Openvpn

    前言 搭建openvpn主要参考这篇博客,原文传送: http://www.jianshu.com/p/4bbf946222d5 所以你会发现步骤基本一样. 安装openvpn A:安装EPEL仓库 ...

  9. java.lang.UnsatisfiedLinkError: dlopen failed: library "libsqlite.so" not found

    项目在7.0以下系统的手机上运行正常,但在7.0的手机上运行异常. 出现这个问题的原因是:从 Android 7.0 开始,Android系统将阻止应用动态链接非公开 NDK 库. 解决方法有两种 第 ...

  10. Linux查看某个端口使用情况并kill

    Linux查看某个端口使用情况并kill 例如查看8083端口的状态: netstat -apn | grep 8083 tcp 0 0 192.168.2.17:8083 0.0.0.0:* LIS ...