poj3728 商务旅行
[Description]
小 T 要经常进行商务旅行,他所在的国家有 N 个城镇,标号为 1,2,3,...,N,这 N 个城镇构
成一棵树。每个城镇可以买入和卖出货物,同一城镇买入和卖出的价格一样,小 T 想从 a
走到 b,在这过程中,在某个城镇买入一个货物,然后在一个城镇卖出,可以是同一城镇买
入和卖出,使得收益最大,注意不能走回头路。
[Input]
第一行一个数 N,第二行 N 个数,第 i 个数表示城镇 i 买入和卖出货物的价格。
接下来 N – 1 行,每行两个数 a,b,表示 a 到 b 之间有一条双向的道路。
接下一行一个数 Q,表示有 Q 个询问,接下来 Q 行,每行两个数 x,y,表示要求小 T 从 x
到 y 的最大收益。
[Output]
对于每个询问,给出一个答案,各占一行。
[Sample Input]
10
16 5 1 15 15 1 8 9 9 15
1 2
1 3
2 4
2 5
2 6
6 7
4 8
1 9
1 10
6
9 1
5 1
1 7
3 3
1 1
3 6
[Sample Output]
7
11
7
0
0
15
[Hint]
对于 50%的数据,0 < n <= 1000,0 < m <= 100
对于 100%的数据,0 < n <= 100000,0 < m <= 10000,0 <= 货物的价格 <= 10^8
设 fa[i][j]表示点 i 的第 2^j 个祖先
ma[i][j]表示点 i 到点 fa[i][j]的最大值。
mi[i][j]表示点 i 到点 fa[i][j]的最小值。
up[i][j]表示点 i 到点 fa[i][j]的最大获利。
down[i][j]表示点 fa[i][j]到点 i 的最大获利。
然后我们可以预处理出这四个数组。
即:
ma[x][i]=max(ma[fa[x][i-1]][i-1],ma[x][i-1]);
mi[x][i]=min(mi[fa[x][i-1]][i-1],mi[x][i-1]);
up[x][i]=max(max(up[fa[x][i-1]][i-1],up[x][i-1]),ma[fa[x][i-1]][i-1]-mi[x][i-1]);
down[x][i]=max(max(down[fa[x][i-1]][i-1],down[x][i-1]),ma[x][i-1]-mi[fa[x][i-1]][i-1]);
在走向最近公共祖先的路径上记录一下历史最小值,在远离最近公共祖先的路径上记录一下历史最大值(在途中和最大获利比较)。最后答案再和历史最大值-历史最小值比较一下即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int next,to;
}edge[];
int head[],num,ans,dep[],val[],flag,n,Q;
int fa[][],Min[][],Max[][],Up[][],Down[][];
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void dfs(int x,int pa)
{int i;
if (dep[x]) return;
dep[x]=dep[pa]+;
for (i=;i<=;i++)
{
fa[x][i]=fa[fa[x][i-]][i-];
Max[x][i]=max(Max[x][i-],Max[fa[x][i-]][i-]);
Min[x][i]=min(Min[x][i-],Min[fa[x][i-]][i-]);
Up[x][i]=max(Up[x][i-],Up[fa[x][i-]][i-]);
Up[x][i]=max(Up[x][i],Max[fa[x][i-]][i-]-Min[x][i-]);
Down[x][i]=max(Down[x][i-],Down[fa[x][i-]][i-]);
Down[x][i]=max(Down[x][i],Max[x][i-]-Min[fa[x][i-]][i-]);
}
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v!=pa)
{
Max[v][]=max(val[v],val[x]);
Min[v][]=min(val[v],val[x]);
Up[v][]=max(,val[x]-val[v]);
Down[v][]=max(,val[v]-val[x]);
fa[v][]=x;
dfs(v,x);
}
}
}
int LCA(int x,int y)
{
int i;
if (dep[x]<dep[y]) swap(x,y);
for (i=;i>=;i--)
if ((<<i)<=dep[x]-dep[y])
{
x=fa[x][i];
}
if (x==y)
{
//cout<<"LCA:"<<' '<<x<<endl;
return x;
}
for (i=;i>=;i--)
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
x=fa[x][];
y=fa[y][];
//cout<<"LCA:"<<' '<<x<<endl;
return x;
}
void get_ans(int x,int y,int lca)
{int i;
int a=,b=,minv=2e9,maxv=;
int small=2e9,large=;
for (i=;i>=;i--)
if ((<<i)<=dep[x]-dep[lca])
{
b=max(b,Up[x][i]);
b=max(b,Max[x][i]-small);
small=min(small,Min[x][i]);
minv=min(minv,Min[x][i]);
x=fa[x][i];
}
for (i=;i>=;i--)
if ((<<i)<=dep[y]-dep[lca])
{
a=max(a,Down[y][i]);
a=max(a,large-Min[y][i]);
large=max(large,Max[y][i]);
maxv=max(maxv,Max[y][i]);
y=fa[y][i];
}
ans=max(a,max(b,maxv-minv));
return;
}
int main()
{int i,u,v,x,y;
freopen("business.in","r",stdin);
freopen("business.out","w",stdout);
cin>>n;
memset(Min,,sizeof(Min));
for (i=;i<=n;i++)
scanf("%d",&val[i]);
for (i=;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(,);
cin>>Q;
while (Q--)
{
scanf("%d%d",&x,&y);
if (x==y) printf("0\n");
else
{
int lca=LCA(x,y);
get_ans(x,y,lca);
printf("%d\n",ans);
}
}
}
poj3728 商务旅行的更多相关文章
- 倍增法-lca codevs 1036 商务旅行
codevs 1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意 ...
- C++之路进阶——codevs1036(商务旅行)
1036 商务旅行 题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇 ...
- 【codevs1036】商务旅行 LCA 倍增
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的 ...
- 2953: [Poi2002]商务旅行
2953: [Poi2002]商务旅行 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 8 Solved: 8[Submit][Status] Desc ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- codevs——1036 商务旅行
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 某首都城市的商人要经常 ...
- codevs1036商务旅行(LCA)
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 某首都城市的商人要经常到各城镇去做 ...
- codevs1026商务旅行
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 某首都城市的商人要经常到各城镇去做 ...
- codevs 1036 商务旅行(Targin求LCA)
传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...
随机推荐
- java中volatile
volatile用来修饰变量.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volat ...
- Access数据库自动生成设计文档
在做Access数据库设计时,常常直接在access文件中建表,建字段,然后写设计文档时,又得重新再写一遍字段和表间关系.其实access数据库自己就支持自动生成数据库文档. 操作方法如下: 数据库工 ...
- Alpha冲刺No.5
一.站立式会议 在助教帮助下,优先解决404的问题,将demo移植到自己项目上. 进一步制作界面. 将已做好的内容,移植到手机做部分测试,能够在同一路由子网内登录数据库. 二.实际项目进展 已经解决了 ...
- 201621123050 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
- 高校征信系统项目Postmortem结果
设想和目标 1 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件需要解决的问题是当前高校学生征信系统建设薄弱的问题,我们试图建立一个征信系统,在完成之后推 ...
- I/O多路转接之poll 函数
poll 一.poll()函数: 这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,自认为poll和select大同小异,下面是这个函数的声明: #include < ...
- 学号:201621123032 《Java程序设计》第2周学习总结
1: 本周学习总结 本周学习java的数据类型,两种数据类型:基本数据类型和引用数据类型. 学习关于String和StringBuilder之间不同. 本周还学习数组.一维数组,多维数组,和动态数组. ...
- 实验二Java面向对象程序设计实验报告(2)
实验二 Java面向对象程序设计 实验概述: 课程:程序设计与数据结构 班级:1623班 姓名: 邢天岳 学号:2309 指导老师:娄老师 王老师 实验日期:2017.4.16 实验名称: Java面 ...
- 【详细】Lucene使用案例
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引 ...
- nyoj 韩信点兵
描述相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排.五人一排.七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了.输入3个非负整数a,b,c ,表示每种队形排尾的人数 ...