题目链接:http://poj.org/problem?id=3728

思路:题目的意思是求树上a -> b的路径上的最大收益(在最小值买入,在最大值卖出)。

我们假设路径a - > b 之间的LCA(a, b) = f, 并且另up[a]表示a - > f之间的最大收益,down[a]表示f - > a之间的最大收益,dp_max[a]表示a - > f之间的最大值,dp_min[a]表示a - > f之间的最小值,于是可以得出关系: ans[id] = max(max(up[a], down[b]), dp_max[b] - dp_min[a])。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;const int MAX_N = (50000 + 5000);
const int MAX_M = (MAX_N << 2);
const int inf = 0x3f3f3f3f;
int NE1, NE2, NE3, head1[MAX_N], head2[MAX_N], head3[MAX_N];void Init()
{NE1 = NE2 = NE3 = 0;memset(head1, -1, sizeof(head1));memset(head2, -1, sizeof(head2));memset(head3, -1, sizeof(head3));}int N, Q, ans[MAX_N], value[MAX_N], vis[MAX_N];struct Edge1 {int v, next;
} edge1[MAX_M];void Insert1(int u, int v)
{edge1[NE1].v = v;edge1[NE1].next = head1[u];head1[u] = NE1++;
}struct Edge {int v, id, next;
} edge2[MAX_M], edge3[MAX_M];void Insert2(int u, int v, int id, int flag)
{if (!flag) {edge2[NE2].v = v;edge2[NE2].id = id;edge2[NE2].next = head2[u];head2[u] = NE2++;} else {edge3[NE3].v = v;edge3[NE3].id = id;edge3[NE3].next = head3[u];head3[u] = NE3++;}
}int parent[MAX_N];
int up[MAX_N], down[MAX_N], dp_max[MAX_N], dp_min[MAX_N];int find(int x)
{if (x == parent[x]) {return x;}int fa = parent[x];parent[x] = find(parent[x]);up[x] = max(max(up[x], up[fa]), dp_max[fa] - dp_min[x]);down[x] = max(max(down[x], down[fa]), dp_max[x] - dp_min[fa]);dp_max[x] = max(dp_max[x], dp_max[fa]);dp_min[x] = min(dp_min[x], dp_min[fa]);return parent[x];
}struct Node {int u, v;
} node[MAX_N];void Tarjan(int u)
{vis[u] = 1;parent[u] = u;//Q;for (int i = head2[u]; ~i; i = edge2[i].next) {int v = edge2[i].v, id = edge2[i].id;if (!vis[v]) continue;int fa = find(v);Insert2(fa, v, id, 1);}for (int i = head1[u]; ~i; i = edge1[i].next) {int v = edge1[i].v;if (vis[v]) continue;Tarjan(v);parent[v] = u;}//edge3for (int i = head3[u]; ~i; i = edge3[i].next) {int id = edge3[i].id;find(node[id].u);find(node[id].v);ans[id] = max(max(up[node[id].u], down[node[id].v]), dp_max[node[id].v] - dp_min[node[id].u]);}
}int main()
{while (~scanf("%d", &N)) {for (int i = 1; i <= N; ++i) {scanf("%d", &value[i]);up[i] = down[i] = 0;dp_max[i] = dp_min[i] = value[i];}Init();for (int i = 1; i < N; ++i) {int u, v;scanf("%d %d", &u, &v);Insert1(u, v);Insert1(v, u);}scanf("%d", &Q);for (int i = 1; i <= Q; ++i) {scanf("%d %d", &node[i].u, &node[i].v);Insert2(node[i].u, node[i].v, i, 0);Insert2(node[i].v, node[i].u, i, 0);}memset(vis, 0, sizeof(vis));Tarjan(1);for (int i = 1; i <= Q; ++i) printf("%d\n", ans[i]);}return 0;
}


转载于:https://www.cnblogs.com/wally/p/4477051.html

poj 3728(LCA + dp)相关推荐

  1. poj 3728 The merchant// lca(倍增实现) + dp || tarjan+并查集路径上dp

    poj 3728 The merchant// lca(倍增实现) + dp Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: ...

  2. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  3. poj 3417 树形dp+LCA

    思路:我以前一直喜欢用根号n分段的LCA.在这题上挂了,第一次发现这样的LCA被卡.果断改用Tarjan离线算法求LCA. 当前节点为u,其子节点为v.那么: 当以v根的子树中含有连接子树以外点的边数 ...

  4. POJ 图论分类 + DP(较全 自己又加了点)

    DP -----------动态规划 状态压缩DP 2411 (棋盘规模较大)状态压缩DP+DFS+滚动数组 2664 (棋盘规模较小)直接递推即可(DP) 2506 (棋盘规模较小)直接递推即可(D ...

  5. POJ 2096 (概率DP)

    题目链接: http://poj.org/problem?id=2096 题目大意:n种bug,s个子系统.每天随机找一个bug,种类随机,来自系统随机.问找齐n种bug,且每个子系统至少有一个bug ...

  6. POJ 2955 (区间DP)

    题目链接: http://poj.org/problem?id=2955 题目大意:括号匹配.对称的括号匹配数量+2.问最大匹配数. 解题思路: 看起来像个区间问题. DP边界:无.区间间隔为0时,默 ...

  7. 目的地返回POJ 2336 动态规划(DP) Ferry Loading II

    在写这篇文章之前,xxx已写过了几篇关于改目的地返回主题的文章,想要了解的朋友可以去翻一下之前的文章 标题链接:http://poj.org/problem?id=2336 分析:想设我们要求的是第i ...

  8. POJ 2342 (树形DP)

    题目链接: http://poj.org/problem?id=2342 题目大意:直属上司和下属出席聚会.下属的上司出现了,下属就不能参加,反之下属参加.注意上司只是指直属的上司.每个人出席的人都有 ...

  9. POJ 3252 数位DP

    链接: http://poj.org/problem?id=3252 题意: 给你一个区间l,r,求区间中有多少个数转化为二进制后1的个数大于等于0的个数 题解: 还是数位dp,不过多了前导0的判断 ...

最新文章

  1. 实验6-选第K小元素
  2. docker配置国内镜像源
  3. 这是一个什么用也没有的模板
  4. CSS的几个属性display,float,clear,overflow,visibility
  5. elasticsearch使用优化备忘
  6. Leetcode算法题(C语言)12--旋转图像
  7. 纺织名词术语(针织品部分)---疵点
  8. 原生开发跟混合开发?两者有什么区别?
  9. Gerrit报错:Permission denied (publickey)
  10. linux6.5关闭防火墙命令,centos关闭防火墙的方法
  11. 怎么查看笔记本内存条型号_内存条,图文告诉您怎么查看内存条的型号
  12. python像数常用函数_引用 象数疗法原理
  13. Excel VLOOKUP 多条件使用
  14. elementui级联选择器
  15. Python实现支持向量机SVM分类模型线性SVM决策过程的可视化项目实战
  16. 知识产权的专利制度来源于何处?
  17. K7的PLL使用问题
  18. 比较不同版本Project所包含的应用与功能
  19. ArcGIS图像配准技巧:配准获取中国气候区分布数据(附练习数据下载)
  20. 华为手机视频解码首屏时延比较大的问题

热门文章

  1. Java - 文件(IO流)
  2. 【Java心得总结六】Java容器中——Collection
  3. 【虚拟主机篇】asp页面实现301重定向方法
  4. css background size
  5. ListView展示SIM信息
  6. 学习《Building Applications with FME Objects》 之四 从数据集读取要素
  7. springboot springcloud区别_SpringBoot回顾、Spring Cloud初学
  8. 前端工业物联网开发(Electron + Typescript + Vue)
  9. AUTOSAR从入门到精通100讲(二)-SOME/IP及其应用
  10. 跨语言、多语言信息检索