POJ 3728 tarjan+DP
来源:互联网 发布:ubuntu 找不到安装包 编辑:程序博客网 时间:2024/05/22 17:25
从这个好题我终于去学了学Tarjan, 因为发现ST毫无意义, 除了预处理, 其他还是要借鉴Tarjan;
Tarjan其实很简单, 其实就是对于询问也开一个邻接表, 两个点的LCA就是:
如果在访问u的时候发现v已经访问过了, 那么LCA就是find(u)
至于这个题up, down, max, min的作用就不说了, 网上的主流代码
是个好题, 初学Tarjan一定要去搞
#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define N 400010#define next Next#define begin Begin#define pb push_back#define mem(a, b) memset(a, b, sizeof(a))#define rep(i, s, t) for(int i = s, end = t; i <= end; ++i)#define erep(i, u) for(int i = begin[u]; i != -1; i = next[i])bool vis[N];int to[N], next[N], begin[N], n, m, q;int e, res[N], w[N];int mx[N], mn[N], up[N], down[N], fa[N];vector<int> query[N], s[N];void add(int u, int v) { to[++e] = v; next[e] = begin[u]; begin[u] = e;}int find(int x) { if(x == fa[x]) return x; int y = fa[x]; fa[x] = find(fa[x]); up[x] = max(mx[y] - mn[x], max(up[x], up[y])); down[x] = max(mx[x] - mn[y], max(down[x], down[y])); mx[x] = max(mx[x], mx[y]); mn[x] = min(mn[x], mn[y]); return fa[x];}void LCA(int u) { int v; vis[u] = 1; for(int i = 0; i < (int) query[u].size(); i += 2) if(vis[v = query[u][i]]) { int f = find(v), id = query[u][i+1]; if(id > 0) s[f].pb(u), s[f].pb(v); else s[f].pb(v), s[f].pb(u); s[f].pb(id > 0? id : -id); } erep(i, u) if(!vis[v = to[i]]){ LCA(v); fa[v] = u; } for(int i = 0; i < (int)s[u].size(); i += 3) { int x = s[u][i], y = s[u][i+1], id = s[u][i+2]; find(x); find(y); res[id] = max(up[x], max(down[y], mx[y] - mn[x])); }}void init() { e = 0; mem(up, 0); mem(down, 0); mem(vis, 0); mem(begin, -1); rep(i, 0, n) fa[i] = i, s[i].clear(), query[i].clear();}int main() {#ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("result.out", "w", stdout);#endif scanf("%d", &n); init(); rep(i, 1, n) { scanf("%d", &w[i]); mx[i] = w[i]; mn[i] = w[i]; } rep(i, 1, n-1) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } scanf("%d", &m); rep(i, 1, m) { int u, v; scanf("%d%d", &u, &v); query[u].pb(v); query[u].pb(i); query[v].pb(u); query[v].pb(-i); } LCA(1); rep(i, 1, m) printf("%d\n", res[i]); /*puts("%----------------%"); rep(i, 1, n) printf("%d %d %d %d\n", up[i], down[i], mx[i], mn[i]); */ return 0;}
VECTOR巨慢。。。。
0 0
- POJ 3728 tarjan+DP
- poj 3160【tarjan缩点+拓扑排序+DP】
- poj 3728 lca问题(tarjan+并查集)+dp思路 (树上买卖的最大收益)
- poj 3728 The merchant(tarjan求lca)
- POJ 3728 The merchant (Tarjan LCA)
- *POJ 3728 - The merchant(LCA‘ Tarjan)
- POJ 3728 The merchant 离线tarjan
- poj 2553 tarjan算法
- poj 2186 tarjan算法
- tarjan求割点 poj 1144
- poj 1470--tarjan--LCA
- POJ 3694 Tarjan+LCA
- poj 2553 tarjan
- poj--1470--tarjan算法
- poj 1523 tarjan求割点
- poj 2553 Tarjan
- poj 1904 Tarjan
- POJ 1470 Tarjan算法
- 【BZOJ3143】游走,概率计算+高斯消元
- POJ 3461 Oulipo (KMP)
- 华为OJ:百钱百鸡
- UIScrollView的底层实现
- 指针函数与函数指针的区别
- POJ 3728 tarjan+DP
- 千万不要在VMWare的NAT模式下使用nmap
- SSH之hibernate学习笔记----关系映射
- 2016.8。18
- KMP模式匹配算法及改进
- Vijos P1059 积木城堡
- 信息转摩尔斯
- 有一种超人叫职场女性
- 说说QQ与微信以及支付宝