题目链接: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;
} //edge3
for (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;
}



poj 3728(LCA + dp)的更多相关文章

  1. Fire (poj 2152 树形dp)

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

  2. POJ 3728 The merchant(LCA+DP)

    The merchant Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total ...

  3. poj 3728 The merchant 倍增lca求dp

    题目: zdf给出的题目翻译: 从前有一个富饶的国度,在这里人们可以进行自由的交易.这个国度形成一个n个点的无向图,每个点表示一个城市,并且有一个权值w[i],表示这个城市出售或收购这个权值的物品.又 ...

  4. POJ 3728 The merchant (树形DP+LCA)

    题目:https://vjudge.net/contest/323605#problem/E 题意:一棵n个点的树,然后有m个查询,每次查询找(u->v)路径上的两个数,a[i],a[j],(i ...

  5. 【题解】POJ 3417 Network(倍增求LCA+DP+树上差分)

    POJ3417:http://poj.org/problem?id=3417 思路 我们注意到由“主要边”构成一颗树 “附加边”则是非树边 把一条附加边(x,y)加入树中 会与树上x,y之间构成一个环 ...

  6. poj 3417 树形dp+LCA

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

  7. poj 3728 The merchant(LCA)

    Description There are N cities in a country, and there is one and only one simple path between each ...

  8. POJ 3278:The merchant(LCA&DP)

    The merchant Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6864   Accepted: 2375 Desc ...

  9. POJ 3728 The merchant(并查集+DFS)

    [题目链接] http://poj.org/problem?id=3728 [题目大意] 给出一棵树,每个点上都可以交易货物,现在给出某货物在不同点的价格, 问从u到v的路程中,只允许做一次买入和一次 ...

随机推荐

  1. java高新技术-可变参数与OverLoad相关面试题分析

    可变参数 可变参数的特点: 只能出现在参数列表的最后: ...位于变量类型和变量名之间,前后有无空格都可以: 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法中以数组的形式访问可变参数 ...

  2. 说说JavaScriptCore

    http://www.jianshu.com/p/1328e15416f3/comments/1724404 javascript目前看来仍是世界上最流行的语言,不管在web.服务端还是客户端都有广泛 ...

  3. Makefile 规则的使用

    1.Makefile格式 //最终目标 all: led.o //依赖 arm-linux-ld -Tled.lds -o led.elf led.o //命令 arm-linux-objcopy - ...

  4. python学习笔记-(十六)python操作mysql

    一. mysql安装 1. windows下安装mysql 1.1. 下载源: http://dev.mysql.com/downloads/installer/,请认准对应版本 Windows (x ...

  5. logo新

  6. javascript数据结构与算法---列表

    javascript数据结构与算法---列表 前言:在日常生活中,人们经常要使用列表,比如我们有时候要去购物时,为了购物时东西要买全,我们可以在去之前,列下要买的东西,这就要用的列表了,或者我们小时候 ...

  7. SQL Server基础知识

    1.SQL Server表名为什么要加方括号? 这个不是必须要加,但表名或字段名如果引用了sqlserver中的关键字,数据库会不识别这到底是关键字还是表名(或字段名)时就必须要加. 比如,一个表名叫 ...

  8. 按Enter键执行表单验证

    document.onkeydown = function(evt){ var evt = window.event?window.event:evt; if (evt.keyCode==13) { ...

  9. springmvc js/css路径问题

    ①No mapping found for HTTP request with URI[/msm2/css/login2.css] in DispatcherServlet with name 'sp ...

  10. Hydra用户手册

    Hydra 参数: -R继续从上一次进度接着破解 -S大写,采用SSL链接 -s <PORT>小写,可通过这个参数指定非默认端口 -l <LOGIN>指定破解的用户,对特定用户 ...