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

【题目大意】

  给出一棵树,每个点上都可以交易货物,现在给出某货物在不同点的价格,
  问从u到v的路程中,只允许做一次买入和一次卖出,最多能得到多少钱。

【题解】

  我们维护一个up表示,x与父节点的连线中,
  最大值在靠近父节点的位置时最小值与最大值的最大差值
  dw表示,x与父节点的连线中,最小值在靠近父节点的位置时最小值与最大值的最大差值
  Min和Max分别表示x到父节点中的最大值和最小值
  对于询问x到y的答案,我们发现以LCA为父节点时,答案只会是dwx,upy,和Maxx-Miny中的最优值,
  所以我们在每个查询的LCA位置计算答案,自低向上维护四个数组,
  这个用并查集就可以顺利完成了。

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N=50010;
int n,m,f[N],ans[N],vis[N],Max[N],Min[N],up[N],dw[N],val[N];
struct edge{int x,id;};
struct data{int x,y;}p[N];
vector<edge> Q[N];
vector<int> G[N],a[N];
int sf(int x){
if(f[x]==x)return x;
int fx=f[x];
f[x]=sf(f[x]);
up[x]=max(max(up[x],up[fx]),Max[fx]-Min[x]);
dw[x]=max(max(dw[x],dw[fx]),Max[x]-Min[fx]);
Max[x]=max(Max[x],Max[fx]);
Min[x]=min(Min[x],Min[fx]);
return f[x];
}
void dfs(int u){
vis[u]=1;
Max[u]=Min[u]=val[u];
up[u]=dw[u]=0;
for(int i=0;i<Q[u].size();i++){
edge e=Q[u][i];
if(vis[e.x])a[sf(e.x)].push_back(e.id);
}
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!vis[v]){dfs(v);f[v]=u;}
}
for(int i=0;i<a[u].size();i++){
int id=a[u][i];
int x=p[id].x,y=p[id].y;
sf(x); sf(y);
ans[id]=max(max(up[x],dw[y]),Max[y]-Min[x]);
ans[id]=max(0,ans[id]);
}
}
void solve(){
for(int i=1;i<=n;i++)scanf("%d",&val[i]);
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);
}for(int i=1;i<=n;i++)f[i]=i;
scanf("%d",&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
Q[u].push_back(edge{v,i});
Q[v].push_back(edge{u,i});
p[i].x=u;p[i].y=v;
}memset(vis,0,sizeof(vis));
dfs(1);
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
}
int main(){
while(~scanf("%d",&n))solve();
return 0;
}

POJ 3728 The merchant(并查集+DFS)的更多相关文章

  1. POJ 1562 Oil Deposits (并查集 OR DFS求联通块)

    Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14628   Accepted: 7972 Des ...

  2. poj 3728 The merchant(LCA)

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

  3. POJ 3728 The merchant(LCA+DP)

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

  4. HDU 1232 并查集/dfs

    原题: http://acm.hdu.edu.cn/showproblem.php?pid=1232 我的第一道并查集题目,刚刚学会,我是照着<啊哈算法>这本书学会的,感觉非常通俗易懂,另 ...

  5. poj 1733(带权并查集+离散化)

    题目链接:http://poj.org/problem?id=1733 思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到 ...

  6. poj 1182 食物链 (并查集)

    http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...

  7. 1021.Deepest Root (并查集+DFS树的深度)

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

  8. POJ 1182 食物链(并查集拆点)

    [题目链接] http://poj.org/problem?id=1182 [题目大意] 草原上有三种物种,分别为A,B,C A吃B,B吃C,C吃A. 1 x y表示x和y是同类,2 x y表示x吃y ...

  9. POJ1291-并查集/dfs

    并查集 题意:找出给定的这些话中是否有冲突.若没有则最多有多少句是对的. /* 思路:如果第x句说y是对的,则x,y必定是一起的,x+n,y+n是一起的:反之x,y+n//y,x+n是一起的. 利用并 ...

随机推荐

  1. Intellij Idea debug 远程部署的的tomcat项目

    web项目部署到tomcat上之后,有时需要打断点单步调试,如果用的是Intellij idea,可以通过如下方法实现: 开启debug端口,启动tomcat 以tomcat7.0.75为例,打开bi ...

  2. IOI1998 Polygon [区间dp]

    [IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...

  3. Saruman’s Level Up~(多校赛算组合数)

    Description Saruman’s army of orcs and other dark minions continuously mine and harvest lumber out o ...

  4. zigbee ---- endpoint理解

    很多资料将其翻译为“端点”,我们不如也这么叫. 在windows上使用不同的软件进行通信,数据包到达不同的应用的方法就是通过寻找IP地址和端口号来确定某一个应用的,也就是我们所说的五元组(源IP,目的 ...

  5. PushState+Ajax 完美实现无刷新

    转载自:http://lazynight.me/1897.html 折腾一下PJAX,利用HTML5的新API,实现历史记录的完美导入. 不知道你用没用过Github,里边的目录跳转就是用html5的 ...

  6. 【Foreign】最大割 [线性基]

    最大割 Time Limit: 15 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 6 1 2 1 1 2 1 3 ...

  7. bzoj4900 [CTSC2017]密钥

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4900 [题解] 恭喜bzoj达到40页 考场由于傻逼基数排序写挂了而gg. 竟然忘了考试前一 ...

  8. 02-更改窗口的根控制器 Demo示例程序源代码

      源代码下载链接:02-更改窗口的根控制器.zip18.0 KB // MJAppDelegate.h // //  MJAppDelegate.h //  02-更改窗口的根控制器 // //  ...

  9. 计算代码行数Demo源码

    源码下载:04-计算代码行数.zip24.1 KB////  main.m//  计算代码行数////  Created by apple on 13-8-12.//技术博客http://www.cn ...

  10. NYOJ 115 城市平乱 (最短路)

    * 题目链接* 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M. 现在,小工军师告诉南将军,第K号城市发生了暴乱,南 ...