LightOJ - 1162 Min Max Roads

题解:在线倍增LCA和模拟ST表

让我们求从\(u->v\)最短路径上的边权最大值和边权最小值,那么我们可以利用倍增思想,类似其\(fa[u][i]\)数组代表从\(u\)往上跳\(2^i\)步的点这一思想,我们可以建立两个二维数组\(dmax[u][i],dmin[u][i]\),代表从\(u\)往上跳\(2^i\)步到达的点和\(u\)之间路径的最大权值和最小权值,同时我们可以知道dmax和dmin的初始状态:\(dmax[u][0]=dmin[u][0]=w_i\),最后类似\(fa[u][i] = fa[fa[u[i-1]]][i-1]\)我们列出状态方程:\(dmax[u][i]=max(dmax[u][i-1],dmax[fa[u][i-1]][i-1])\),\(dmin[u][i]=min(dmin[u][i-1],dmin[fa[u][i-1]][i-1])\),

这就类似ST表的思想,一个区间的最大值是可重复的贡献,所以我们各取区间的一半分别取\(max/min\),所以这个方程就代表:从\(u\)往上跳\(2^i\)步到达的点和\(u\)之间路径的最大权值和最小权值,\([u,2^i] = max/min([u,2^{i-1}],[u+2^{i-1},u+2^i])\)

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 1e5 + 10;
int n, m;
int fa[N][22], dmax[N][22], dmin[N][22];
int du[N], dep[N];
vector<pii> g[N];
void init()
{
memset(fa, 0, sizeof fa);
memset(dmax, 0, sizeof dmax);
memset(dmin, 0, sizeof dmin);
for (int i = 1; i <= n; ++i)
du[i] = 0, dep[i] = 0, g[i].clear();
}
void dfs(int u, int par, int w)
{
dep[u] = dep[par] + 1;
fa[u][0] = par;
dmax[u][0] = w;
dmin[u][0] = w;
for (int i = 1; i <= 20; ++i)
{
fa[u][i] = fa[fa[u][i - 1]][i - 1];
dmax[u][i] = max(dmax[u][i - 1], dmax[fa[u][i - 1]][i - 1]);
dmin[u][i] = min(dmin[u][i - 1], dmin[fa[u][i - 1]][i - 1]);
}
for (auto &[v, W] : g[u])
{
if (v == par)
continue;
dfs(v, u, W);
}
}
void lca(int u, int v)
{
int maxx = -inf, minn = inf;
if (dep[u] < dep[v])
swap(u, v);
for (int i = 20; i >= 0; i--)
{
if (dep[fa[u][i]] >= dep[v])
{
maxx = max(maxx, dmax[u][i]); //注意一定要先去取区间max和min,不然u就会改变
minn = min(minn, dmin[u][i]);
u = fa[u][i];
}
}
if (u == v)
{
cout << minn << " " << maxx << endl;
return;
}
for (int i = 20; i >= 0; --i)
{
if (fa[u][i] != fa[v][i])
{
maxx = max({maxx, dmax[u][i], dmax[v][i]});
minn = min({minn, dmin[u][i], dmin[v][i]});
u = fa[u][i], v = fa[v][i];
}
}
maxx = max({maxx, dmax[u][0], dmax[v][0]});
minn = min({minn, dmin[u][0], dmin[v][0]});
cout << minn << " " << maxx << endl;
}
int main(void)
{
Zeoy;
int t = 1;
cin >> t;
int tot = 1;
while (t--)
{
cin >> n;
cout << "Case " << tot++ << ":\n";
init();
for (int i = 1, u, v, w; i < n; ++i)
{
cin >> u >> v >> w;
du[v]++;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
int st;
for (int i = 1; i <= n; ++i)
{
if (du[i] == 0)
{
st = i;
break;
}
}
dfs(st, 0, 0);
cin >> m;
for (int i = 1, u, v; i <= m; ++i)
{
cin >> u >> v;
lca(u, v);
}
}
return 0;
}

最新文章

  1. WIN7下查看CPU核心数
  2. Android studio 英文——中文 翻译插件
  3. JavaScript的客户端存储
  4. 《实战Java虚拟机》,最简单的JVM入门书,京东活动,满200就减100了,该出手了
  5. java 求 两个数的百分比% (转)
  6. JavaScript中如何中断forEach循环
  7. Scrum 项目4.0--软件工程
  8. Android Training精要(三)不同分辨率图片缩放倍数
  9. Trie三兄弟——标准Trie、压缩Trie、后缀Trie
  10. [LeetCode]题解(python):020-Valid Parentheses
  11. 如何估算网站日承受最大访问PV
  12. 自己开发轻量级ORM(二)
  13. R语言进行机器学习方法及实例(一)
  14. html5+ XMLHttpRequest
  15. php 获取URL 各部分参数
  16. html&amp;css学习笔记----YJZJZQA
  17. linux 之 shell
  18. Django的model form组件
  19. elasticsearch elk最全java api 搜索 聚合、嵌套查询
  20. SQL基础语法提纲

热门文章

  1. SpringMVC的常用注解、参数绑定、转发与重定向
  2. Spring(Ioc DI、Spring的继承-依赖)
  3. TreeMap排序Comparator()重写
  4. P5787 二分图 /【模板】线段树分治
  5. bootstrap怎么让手机端电脑端自适应显示隐藏元素
  6. python 操作 WhiteSpace 语言
  7. sql 查找连续的时间区间以及连续天数
  8. 一次线上OOM问题分析
  9. 深入理解计算机系统(CSAPP)bomblab实验进阶之nuclearlab——详细题解
  10. ELK 一些截图