poj3728The merchant 【倍增】【LCA】
There are N cities in a country, and there is one and only one simple path between each pair of cities. A merchant has chosen some paths and wants to earn as much money as possible in each path. When he move along a path, he can choose one city to buy some goods and sell them in a city after it. The goods in all cities are the same but the prices are different. Now your task is to calculate the maximum possible profit on each path.
Input
The first line contains N, the number of cities.
Each of the next N lines contains wi the goods' price in each city.
Each of the next N-1 lines contains labels of two cities, describing a road between the two cities.
The next line contains Q, the number of paths.
Each of the next Q lines contains labels of two cities, describing a path. The cities are numbered from 1 to N.
1 ≤ N, wi, Q ≤ 50000
Output
The output contains Q lines, each contains the maximum profit of the corresponding path. If no positive profit can be earned, output 0 instead.
Sample Input
4
1
5
3
2
1 3
3 2
3 4
9
1 2
1 3
1 4
2 3
2 1
2 4
3 1
3 2
3 4
Sample Output
4
2
2
0
0
0
0
2
0
倍增 LCA还是完全不会写.....
所以是看的题解
刚开始完全不能理解为什么这道题也能转换成LCA 找得到公共祖先然后呢 然后呢 然后呢
建的图相当于一个dfs树 路径是唯一的
找公共祖先t就相当于找到这条路径 公共祖先把这个路径分成了两半
最后(u, v)的答案有三种可能
1.u到t完成了买和卖
2.t到v完成了买和卖
3.在u到t某点买,t到v某点卖
因此现在需要一个up数组,up[i][j]维护i到i节点往上2^j的节点的最大差价
down数组,down[i][j]维护i到i节点往下2^j的节点的最大差价
Max数组, Max[i][j]维护i到i节点往上2^j的节点之间价格的最大值
Min数组,Min[i][j]维护i到i节点往上2^j的节点之间价格的最小值
parent数组,parent[i][0]存储每个节点的父亲,用dfs先预处理出来。用倍增的思想处理出parent[i][j]表示i往上2^j的节点
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <stack>
#define inf 0x3f3f3f3f
using namespace std;
int n, q, ecnt;
const int maxn = 50005;
int Max[maxn][20], Min[maxn][20], up[maxn][20], down[maxn][20], parent[maxn][20];
vector <int> g[maxn];
int dep[maxn],val[maxn];
void dfs(int u, int fa)
{
for(int i = 0; i < g[u].size(); i++){
int v = g[u][i];
if(v == fa) continue;
dep[v] = dep[u] + 1;
parent[v][0] = u;
Max[v][0] = max(val[v], val[u]);
Min[v][0] = min(val[v], val[u]);
down[v][0] = max(0, val[v] - val[u]);
up[v][0] = max(0, val[u] - val[v]);
dfs(v, u);
}
}
void init()
{
dep[1] = 1;
memset(parent, -1, sizeof(parent));
dfs(1, 0);
for(int j = 1; (1 << j) <= n; j++){
for(int i = 1; i <= n; i++){
if(~parent[i][j - 1]){
int k = parent[i][j - 1], a, b;
parent[i][j] = parent[k][j - 1];
Max[i][j] = max(Max[i][j - 1], Max[k][j - 1]);
Min[i][j] = min(Min[i][j - 1], Min[k][j - 1]);
a = max(0, Max[i][j - 1] - Min[k][j - 1]), b = max(down[i][j - 1], down[k][j - 1]);
down[i][j] = max(a, b);
a = max(0, Max[k][j - 1] - Min[i][j - 1]), b = max(up[i][j - 1], up[k][j - 1]);
up[i][j] = max(a,b);
}
}
}
}
int LCA(int a, int b)
{
if(dep[a] < dep[b]) swap(a, b);
int i;
for(i = 0; (1 << i) <= dep[a]; i++);
i--;
for(int j = i; j >= 0; j--){
if(dep[a] - (1 << j) >= dep[b]){
a = parent[a][j];
}
}
if(a == b){
return a;
}
for(int j = i; j >= 0; j--){
if(parent[a][j] != -1 && parent[a][j] != parent[b][j]){
a = parent[a][j];
b = parent[b][j];
}
}
return parent[a][0];
}
int query_down(int x, int k, int &max_val)
{
int ans = 0;
max_val = 0;
for(int i = 18; i >= 0; i--){
if(k & (1 << i)){
ans = max(ans, down[x][i]);
ans = max(ans, max_val - Min[x][i]);
max_val = max(max_val, Max[x][i]);
x = parent[x][i];
}
}
return ans;
}
int query_up(int x, int k, int &min_val)
{
int ans = 0;
min_val = inf;
for(int i = 18; i >= 0; i--){
if(k & (1 << i)){
ans = max(ans, up[x][i]);
ans = max(ans, Max[x][i] - min_val);
min_val = min(min_val, Min[x][i]);
x = parent[x][i];
}
}
return ans;
}
int main()
{
while(scanf("%d", &n) != EOF){
for(int i = 1; i <= n; i++){
scanf("%d", &val[i]);
}
for(int i = 1; i <= n; i++){
g[i].clear();
}
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
init();
scanf("%d", &q);
while(q--){
int u, v;
scanf("%d%d", &u, &v);
int t = LCA(u, v);
int min_val, max_val, a, b;
a = query_up(u, dep[u] - dep[t], min_val);
b = query_down(v, dep[v] - dep[t], max_val);
int ans = max(max(0, max_val - min_val), max(a, b));
cout<<ans<<endl;
}
}
return 0;
}
poj3728The merchant 【倍增】【LCA】的更多相关文章
- POJ3728The merchant (倍增)(LCA)(DP)(经典)(||并查集压缩路径?)
There are N cities in a country, and there is one and only one simple path between each pair of citi ...
- poj 3728 The merchant 倍增lca求dp
题目: zdf给出的题目翻译: 从前有一个富饶的国度,在这里人们可以进行自由的交易.这个国度形成一个n个点的无向图,每个点表示一个城市,并且有一个权值w[i],表示这个城市出售或收购这个权值的物品.又 ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- Gym100685G Gadget Hackwrench(倍增LCA)
题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...
- Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]
题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...
- hdu 4674 Trip Advisor(缩点+倍增lca)
花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- codevs 1036 商务旅行 (倍增LCA)
/* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...
随机推荐
- 谈谈入门iOS的经验吧
前言 近期忙完项目比較闲,想写一篇博客来分享一些自学iOS的心得体会,希望对迷茫的你有所帮助.博主非科班出身,一些计算机术语上的不专业欢迎大家指正. 我是学微电子的.大四的时候找了一家深圳的专业对口的 ...
- jackson 转换 enum 类型
REST API 接口要求 requster json 的 lifeCycle 域只能填 YOUNG, OLD,对于其他的 lifeCycle,都要给 requester 返回 bad request ...
- 【代码审计】JTBC(CMS)_PHP_v3.0 任意文件上传漏洞分析
0x00 环境准备 JTBC(CMS)官网:http://www.jtbc.cn 网站源码版本:JTBC_CMS_PHP(3.0) 企业版 程序源码下载:http://download.jtbc. ...
- Kafka(一)-- 初体验
一.概念 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素. 这些 ...
- metasploit 中的DB
渗透测试任务中,主机/服务/漏洞等信息如果手动维护,会带来巨大的工作量. 在metasploit中,这部分工作已经被封装的非常好,每次调用内部模块执行的任务结果都会自动存入DB.通过简单的指令即可以方 ...
- 高并发应对:淘宝CDN缓存服务器部署探秘
转自:http://server.chinabyte.com/6/12663506.shtml “好,时间到,开抢!”坐在电脑前早已等待多时的宋兰(化名)一看时间已到2011年11月11日零时,便迫不 ...
- Apache Kafka 0.11版本新功能简介
Apache Kafka近日推出0.11版本.这是一个里程碑式的大版本,特别是Kafka从这个版本开始支持“exactly-once”语义(下称EOS, exactly-once semantics) ...
- 手机CPU天梯图2018年5月最新版
话不多说,以下是2018年5月最新的手机CPU天梯图精简版,由于最近一两个月,芯片厂商发布的新Soc并不不多,因此这次天梯图更新,主要是来看看今年主流手机厂商都流行使用哪些处理器. 手机CPU天梯图2 ...
- 【linux】 scrapy : Could not find a version that satisfies the requirement Twisted>=13.1.0 (from Scrapy) (from versions: )
centos7 + python3 安装 scrapy 时候报错,错误信息如下: Could not find a version that satisfies the requirement Twi ...
- Python中四种运行其他程序的方式
原文地址:http://blog.csdn.net/jerry_1126/article/details/46584179 在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在 ...