POJ 3728 The merchant
来源:互联网 发布:solarman软件下载 编辑:程序博客网 时间:2024/05/01 07:05
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=34528#problem/L
#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 50010;const int POW = 17;const int INF = 0x3f3f3f3f;int val[MAXN], head[MAXN], cnt;int parent[MAXN][POW], dep[MAXN], mmin[MAXN][POW], mmax[MAXN][POW], up[MAXN][POW], down[MAXN][POW];/**parent[i][j]: 表示距离顶点i为2^j的祖先顶点的编号*up[i][j]: i->距离i为2^j的祖先顶点最大收益*down[i][j]: 距离i为2^j的祖先顶点->i顶点的最小收益*mmin[i][j]: i->距离i为2^j的祖先顶点的最小顶点的权值*mmax[i][j]: i->距离i为2^j的祖先顶点的最大顶点的权值*因此对于一组询问(u,v) ans = max(getmax_up(u, lca(u,v)), getmax_dwon(v, lca(u,v)), getmax(v, lca(u,v))-getmin(u, lca(u,v)))*/struct Edge{ int v, next; Edge() {} Edge(int t_v, int t_next) : v(t_v), next(t_next) {}}edge[2*MAXN];void addedge(int u, int v){ edge[cnt].v = v; edge[cnt].next = head[u]; head[u] = cnt++; edge[cnt].v = u; edge[cnt].next = head[v]; head[v] = cnt++;}void Init(int n){ cnt = 0; memset(head, -1, sizeof(head)); memset(dep, 0, sizeof(dep)); memset(parent, 0, sizeof(parent)); for(int i = 1; i <= n; ++i) { for(int j = 0; j < POW; ++j) { mmin[i][j] = mmax[i][j] = up[i][j] = down[i][j] = 0; } }}void dfs(int u, int fa){ int i, j; dep[u] = dep[fa] + 1; for(i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(v == fa) continue; //////////////////////////////////////////////////////////////////////////////// parent[v][0] = u; mmin[v][0] = min(val[u], val[v]); mmax[v][0] = max(val[u], val[v]); up[v][0] = val[u] - val[v]; down[v][0] = val[v] - val[u]; for(j = 1; (1<<j) <= dep[u] + 1; j++) { parent[v][j] = parent[parent[v][j-1]][j-1]; mmin[v][j] = min(mmin[v][j-1], mmin[parent[v][j-1]][j-1]); mmax[v][j] = max(mmax[v][j-1], mmax[parent[v][j-1]][j-1]); up[v][j] = max(up[v][j-1], up[parent[v][j-1]][j-1]); up[v][j] = max(up[v][j], mmax[parent[v][j-1]][j-1] - mmin[v][j-1]); down[v][j] = max(down[v][j-1], down[parent[v][j-1]][j-1]); down[v][j] = max(down[v][j], mmax[v][j-1] - mmin[parent[v][j-1]][j-1]); } ///////////////////////////////////////////////////////////////////////////////// dfs(v, u); } return ;}int LCA(int u, int v){ int i; if(dep[u] > dep[v]) u ^= v, v ^= u, u ^= v; if(dep[u] < dep[v]) { int del = dep[v] - dep[u]; for(i = 0; i < POW; i++) if(del & (1<<i)) v = parent[v][i]; } if(u != v) { for(i = POW - 1; i >= 0; i--) if(parent[u][i] != parent[v][i]) u = parent[u][i], v = parent[v][i]; u = parent[u][0], v = parent[v][0]; } return u;}int getmax_up(int u, int v){ int ans = 0, i, tmp = INF; int del = dep[u] - dep[v]; for(i = POW-1; i >= 0; i--) { if(del & (1<<i)) { ans = max(ans, up[u][i]); ans = max(ans, mmax[u][i] - tmp); tmp = min(tmp, mmin[u][i]); u = parent[u][i]; } } return ans;}int getmax_down(int u, int v){ int ans = 0, i, tmp = 0; int del = dep[u] - dep[v]; for(i = POW-1; i >= 0; i--) { if(del & (1<<i)) { ans = max(ans, down[u][i]); ans = max(ans, tmp - mmin[u][i]); tmp = max(tmp, mmax[u][i]); u = parent[u][i]; } } return ans;}int getmax(int u, int v){ int ans = 0, i; int del = dep[u] - dep[v]; for(i = POW-1; i >= 0; i--) { if(del & (1<<i)) { ans = max(ans, mmax[u][i]); u = parent[u][i]; } } return ans;}int getmin(int u, int v){ int ans = INF, i; int del = dep[u] - dep[v]; for(i = POW-1; i >= 0; i--) { if(del & (1<<i)) { ans = min(ans, mmin[u][i]); u = parent[u][i]; } } return ans;}void solve(int u, int v){ int lca = LCA(u, v); int a, b, c, d; a = getmax_up(u, lca); b = getmax_down(v, lca); c = getmin(u, lca); d = getmax(v, lca); printf("%d\n", max(max(a, b), d - c));}int main(){ //freopen("aa.in", "r", stdin); int i, u, v, n, q; scanf("%d", &n); Init(n); for(i = 1; i <= n; i++) scanf("%d", &val[i]); for(i = 1; i < n; i++) { scanf("%d %d", &u, &v); addedge(u, v); } dfs(1, 0); scanf("%d", &q); for(i = 1; i <= q; i++) { scanf("%d %d", &u, &v); solve(u, v); } return 0;}
- POJ 3728 The merchant
- poj 3728 The merchant
- POJ 3728 The merchant
- POJ-3728-The merchant
- POJ 3728 【The merchant】
- POJ 3728 The merchant
- POJ 3728 The merchant
- poj 3728 The merchant
- POJ 3728 The merchant
- The merchant - POJ 3728 LCA
- POJ 3728:The merchant LCA
- |poj 3728|LCA|The merchant
- poj 3728 The merchant(tarjan求lca)
- POJ 3728 The merchant (Tarjan LCA)
- POJ 3728 The merchant LCA+倍增dp
- *POJ 3728 - The merchant(LCA‘ Tarjan)
- POJ - 3728 The merchant(dp+LCA)
- POJ 3728The merchant (LCA)
- Java中二维数组的长度
- ubuntu 13.10 & Ubuntu 14.04 64位安装及配置 google拼音输入法及Adobe flash player、mp3 插件安装、中文GBK编码等
- EASYUI+MVC4+VS2010通用权限管理系统开发
- Bos启动测试,服务端就绪,客户端不会启动
- PorterDuff.Mode
- POJ 3728 The merchant
- hibernate中session的get()、load()方法比较
- cocos2d-x中文文档和例子程序
- 彼得•德鲁克 (Peter F.Drucker)管理思想
- storm 单机版安装
- Android之旅 笔记总结(一)
- C位操作
- 【交互】MFC各个类之间相互访问分析
- 过滤器与拦截器