博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
阅读量:5880 次
发布时间:2019-06-19

本文共 2308 字,大约阅读时间需要 7 分钟。

 

题意:

  有n个点的一棵树。其中树上有m条已知的链,每条链有一个权值。从中选出任意个不相交的链使得链的权值和最大。

思路:

  树形DP。设dp[i]表示i的子树下的最优权值和,sum[i]表示不考虑i点时子树的最优权值和,即(j是i的儿子),显然dp[i]>=sum[i]。那么问题是考虑i点时dp[i]的值是多少,假设有一条链通过i,且端点a和b都在i的子树里,即LCA(a,b)=i,如果考虑加上这条链的权值,那么a->i, b->i的路上的点v都不能有链经过它们(题目要求链不相交),那么-dp[v],但至少有sum[v],即,其中v是某条链上的点。那么怎么快速求出sigma的值呢,想到树状数组维护前缀和。那么怎么遍历呢,用DFS序遍历,思想和“”一样,在L[v]上修改,在R[v]上恢复。

#include 
using namespace std;const int N = 1e5 + 5;const int D = 20;struct Chain { int u, v, w;};vector
chains[N];vector
edges[N];int dp[N], sum[N];int n, m;int tim;void init() { for (int i=1; i<=n; ++i) { edges[i].clear (); chains[i].clear (); }}int rt[N][D], dep[N];void init_LCA() { for (int j=1; j
> i & 1) { u = rt[u][i]; } } if (u == v) return u; for (int i=D-1; i>=0; --i) { if (rt[u][i] != rt[v][i]) { u = rt[u][i]; v = rt[v][i]; } } return rt[u][0];}struct BIT { int C[N]; int n; void init(int n) { this->n = n; memset (C, 0, sizeof (C)); } void updata(int i, int x) { for (; i<=n; i+=i&-i) C[i] += x; } int query(int i) { int ret = 0; for (; i>0; i-=i&-i) ret += C[i]; return ret; }}bsum, bdp;int L[N], R[N];void DFS(int u, int pa) { L[u] = tim++; dep[u] = dep[pa] + 1; rt[u][0] = pa; for (auto v: edges[u]) { if (v == pa) continue; DFS (v, u); } R[u] = tim;}void DFS(int u) { sum[u] = 0; for (auto v: edges[u]) { if (v == rt[u][0]) continue; DFS (v); sum[u] += dp[v]; } dp[u] = sum[u]; for (auto chain: chains[u]) { int a = chain.u, b = chain.v, c = chain.w; int tmp = bsum.query (L[a]) - bdp.query (L[a]) + bsum.query (L[b]) - bdp.query (L[b]); dp[u] = max (dp[u], sum[u] + tmp + c); } bsum.updata (L[u], sum[u]); bsum.updata (R[u], -sum[u]); bdp.updata (L[u], dp[u]); bdp.updata (R[u], -dp[u]);}void prepare() { dep[0] = 0; tim = 1; DFS (1, 0); init_LCA (); bsum.init (n); bdp.init (n);}int main() { int T; scanf ("%d", &T); while (T--) { init (); scanf ("%d%d", &n, &m); for (int i=1; i

  

转载于:https://www.cnblogs.com/Running-Time/p/5680092.html

你可能感兴趣的文章
SpringMVC案例1——对User表进行CRUD操作
查看>>
[Contiki系列论文之1]Contiki——为微传感器网络而生的轻量级的、灵活的操作系统...
查看>>
Android 网络编程 记录
查看>>
微软同步发行Windows 10和Windows 10 Mobile系统更新
查看>>
Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二)
查看>>
form表单下的button按钮会自动提交表单的问题
查看>>
那些年追过的......写过的技术博客
查看>>
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>
C# 解决窗体闪烁
查看>>
CSS魔法堂:Transition就这么好玩
查看>>
【OpenStack】network相关知识学习
查看>>
centos 7下独立的python 2.7环境安装
查看>>
[日常] 算法-单链表的创建
查看>>
前端工程化系列[01]-Bower包管理工具的使用
查看>>
使用 maven 自动将源码打包并发布
查看>>
Spark:求出分组内的TopN
查看>>
Python爬取豆瓣《复仇者联盟3》评论并生成乖萌的格鲁特
查看>>
关于跨DB增量(增、改)同步两张表的数据小技巧
查看>>
学员会诊之03:你那惨不忍睹的三层架构
查看>>
vue-04-组件
查看>>