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;
}

LightOJ - 1162 Min Max Roads的更多相关文章

  1. 在一定[min,max]区间,生成n个不重复的随机数的封装函数

    引:生成一个[min,max]区间的一个随机数,随机数生成相关问题参考→链接 var ran=parseInt(Math.random()*(max-min+1)+min); //生成一个[min,m ...

  2. LINQ to SQL Count/Sum/Min/Max/Avg Join

    public class Linq { MXSICEDataContext Db = new MXSICEDataContext(); // LINQ to SQL // Count/Sum/Min/ ...

  3. 2.10 用最少次数寻找数组中的最大值和最小值[find min max of array]

    [本文链接] http://www.cnblogs.com/hellogiser/p/find-min-max-of-array.html [题目] 对于一个由N个整数组成的数组,需要比较多少次才能把 ...

  4. LINQ Count/Sum/Min/Max/Avg

    参考:http://www.cnblogs.com/peida/archive/2008/08/11/1263384.html Count/Sum/Min/Max/Avg用于统计数据,比如统计一些数据 ...

  5. 【转载】:【C++跨平台系列】解决STL的max()与numeric_limits::max()和VC6 min/max 宏冲突问题

    http://www.cnblogs.com/cvbnm/articles/1947743.html 多年以前,Microsoft 幹了一件比 #define N 3 還要蠢的蠢事,那就是在 < ...

  6. LINQ to SQL 语句(3) 之 Count/Sum/Min/Max/Avg

    LINQ  to SQL 语句(3) 之  Count/Sum/Min/Max/Avg [1] Count/Sum 讲解 [2] Min 讲解 [3] Max 讲解 [4] Average 和 Agg ...

  7. [转]LINQ语句之Select/Distinct和Count/Sum/Min/Max/Avg

    在讲述了LINQ,顺便说了一下Where操作,这篇开始我们继续说LINQ语句,目的让大家从语句的角度了解LINQ,LINQ包括LINQ to Objects.LINQ to DataSets.LINQ ...

  8. 动态规划——min/max的单调性优化总结

    一般形式: $max\{min(ax+by+c,dF(x)+eG(y)+f)\},其中F(x)和G(y)是单调函数.$ 或 $min\{max(ax+by+c,dF(x)+eG(y)+f)\},其中F ...

  9. Hive函数:SUM,AVG,MIN,MAX

    转自:http://lxw1234.com/archives/2015/04/176.htm,Hive分析窗口函数(一) SUM,AVG,MIN,MAX 之前看到大数据田地有关于max()over(p ...

  10. 产生10个随机数5-9之间 统计一个int类型的一维数组中有多少个在[min,max]之间的数

    * 产生10个随机数5-9之间 统计一个int类型的一维数组中有多少个在[min,max]之间的数 */ import java.util.*; public class Demo{ public s ...

随机推荐

  1. JavaScript数组的方法大全(最新)

    JavaScript数组方法大全 趁着有时间,总结了下数组所有的属性和方法,记录博客,便于后续使用 array.at() at方法,用于获取数组中,对应索引位置的值,不能修改. 语法:array.at ...

  2. python实现移动二级目录下的文件到一级目录

    python实现移动二级目录下的文件到一级目录 import os import shutil import sys def move_to_work_folder(work_path, cur_pa ...

  3. C#/VB.NET 如何在 Word 文档中添加页眉和页脚

    页眉位于文档中每个页面的顶部区域,常用于显示文档的附加信息,可以插入时间.图形.公司微标.文档标题.文件名或作者姓名等:页脚位于文档中每个页面的底部的区域,常用于显示文档的附加信息,可以在页脚中插入文 ...

  4. LeetCode-2044 统计按位或能得到最大值子集的数目

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/count-number-of-maximum-bitwise-or-subsets 题目描述 给 ...

  5. web生命周期概览

    1, 输入URL(或单击连接). 2, 生成请求并发送至服务器. 3,执行某些动作或者获取某些资源;将响应发送给客户端. 4,处理HTML,CSS和JavaScript并构建结果页面. 5,监控事件队 ...

  6. 阿里云oss初使用

    一.购买 二.配置RAM权限 https://ram.console.aliyun.com/users 1.创建用户 2.创建完成后注意获取AccessKey ID.AccessKey Secret( ...

  7. 2.3 在DispatcherServlet的构造方法中解析applicationContext.xml配置文件

    package com.hy.servlet; import java.io.IOException; import java.io.InputStream; import java.util.Map ...

  8. VMware-实用网站

    二进制包的获取方式 ftp://ftp.redhat.com推荐网站  www.rpmfind.net相应的官方网站http://www.mysql.com

  9. MySQL安装最后一步无响应解决方法

    一.卸载及安装 MySQL安装到最后一步就卡住,如图: 卸载原来安装的MySQL1.首先,卸载MySQL:2.然后,删除C盘下(C:\ProgramData\MySQL)文件: 然后重新安装MySQL ...

  10. vue 清空element表单数据

    resetFields是用于针对整个表单的 Form Methods(整个表单) resetField 是针对表单项的 Form-Item Methods(表单的某一个项) this.$refs['e ...