BJ模拟(2) D2T3 路径规划

2023-11-02 11:38
文章标签 规划 路径 模拟 bj d2t3

本文主要是介绍BJ模拟(2) D2T3 路径规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

路径规划

题目背景:

thoj27

分析:这道题我打了一个暴力,用树链剖分实现不知道为什么前两个点都没有过,但是别人完全不优化的暴力竟然都过了,这样我很不服啊,不开心qnq,本来呢,这道题敲一个无脑的点分是可以卡卡常数过的,复杂度O(nlog2n),但是正如某学长所说,这样非常的不优雅,那我们考虑一些优雅些的做法,首先我们这里给出一个结论。对于树上的两个不相交的点集ST,若集合S中的最长链(即直径)是Sx à Sy,集合T内的最长链(直径)是Tx à Ty 那么如果我们合并这两个点集,那么现在的合并的点集的最长链(直径)一定是,Sx à Sy, Sx à Tx, Sx à Ty, Sy à Tx, Sy à Ty, Tx à Ty6条中的一个,那现在问题就简单了,我们将树边按照边权由大到小直接排序,对于然后维护连通块直径,每一次将边两端的连通块合并,然后更新新的直径就可以了,这样的复杂度为O(nlogn)

Source

#include #include #include #include #include #include #include #include using namespace std; inline char read() { static const int IN_LEN = 1024 * 1024; static char buf[IN_LEN], *s, *t; if (s == t) { t = (s = buf) + fread(buf, 1, IN_LEN, stdin); if (s == t) return -1; } return *s++; } template inline bool R(T &x) { static char c; static bool iosig; for (c = read(), iosig = false; !isdigit(c); c = read()) { if (c == -1) return false; if (c == '-') iosig = true; } for (x = 0; isdigit(c); c = read()) x = (x << 3) + (x << 1) + (c ^ '0'); if (iosig) x = -x; return true; } const int OUT_LEN = 1024 * 1024; char obuf[OUT_LEN], *oh = obuf; inline void writechar(char c) { if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf; *oh++ = c; } template inline void W(T x) { static int buf[30], cnt; if (!x) writechar(48); else { if (x < 0) writechar('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) writechar(buf[cnt--]); } } inline void flush() { fwrite(obuf, 1, oh - obuf, stdout); } const int MAXN = 300000 + 10; struct data { int u, v, w; data(int u, int v, int w) : u(u), v(v), w(w) {} data() {} bool operator < (const data &a) const { return w > a.w; } } side[MAXN]; struct node { int to, w; node(int to, int w) : to(to), w(w) {} node() {} }; vector edge[MAXN]; struct Tree { int top; int size; int son; int father; int dis; int dep; int num; } tree[MAXN]; struct comp { int x, y; comp(int x, int y) : x(x), y(y) {} comp() {} } dis[MAXN]; int ind, n, x, y, z; int father[MAXN], pos[MAXN]; inline void addEdge(int u, int v, int w) { edge[u].push_back(node(v, w)); edge[v].push_back(node(u, w)); } inline void dfs1(int cur, int fa, int w) { tree[cur].size = 1; tree[cur].father = fa; tree[cur].dis = tree[fa].dis + w;; tree[cur].dep = tree[fa].dep + 1; for (int p = 0; p < edge[cur].size(); ++p) if (edge[cur][p].to != fa) { dfs1(edge[cur][p].to, cur, edge[cur][p].w); tree[cur].size += tree[edge[cur][p].to].size; if (!tree[cur].son || tree[tree[cur].son].size < tree[edge[cur][p].to].size) tree[cur].son = edge[cur][p].to; } } inline void dfs2(int cur, int top) { tree[cur].top = top; tree[cur].num = ++ind; pos[ind] = cur; if (tree[cur].son) dfs2(tree[cur].son, top); for (int p = 0; p < edge[cur].size(); ++p) if (!tree[edge[cur][p].to].num) dfs2(edge[cur][p].to, edge[cur][p].to); } /*这里的树链剖分只是用来求lca*/ inline int query_length(int u, int v) { int p = u, q = v; while (tree[u].top != tree[v].top) { int x = tree[u].top, y = tree[v].top; if (tree[x].dep > tree[y].dep) u = tree[x].father; else v = tree[y].father; } if (tree[u].dep > tree[v].dep) return tree[p].dis + tree[q].dis - 2 * tree[v].dis; else return tree[p].dis + tree[q].dis - 2 * tree[u].dis; } inline void readin() { R(n); for (int i = 1; i < n; ++i) { R(x), R(y), R(z); addEdge(x, y, z); side[i] = data(x, y, z); } } inline int getfather(int x) { return (father[x] == x) ? x : (father[x] = getfather(father[x]), father[x]); } inline bool update(long long &x, int y) { return (x < y) ? (x = y, true) : false; } inline void work() { long long ans = 0; sort(side + 1, side + n); for (int i = 1; i <= n; ++i) father[i] = i, dis[i] = comp(i, i); for (int i = 1; i < n; ++i) { int fa1 = getfather(side[i].u), fa2 = getfather(side[i].v); long long cur = 0; int x1 = dis[fa1].x, y1 = dis[fa1].y; int x2 = dis[fa2].x, y2 = dis[fa2].y; int a, b; if (update(cur, query_length(x1, y1))) a = x1, b = y1; if (update(cur, query_length(x1, x2))) a = x1, b = x2; if (update(cur, query_length(x1, y2))) a = x1, b = y2; if (update(cur, query_length(y1, x2))) a = y1, b = x2; if (update(cur, query_length(y1, y2))) a = y1, b = y2; if (update(cur, query_length(x2, y2))) a = x2, b = y2; father[fa1] = fa2, dis[fa2] = comp(a, b); ans = max(ans, 1LL * side[i].w * query_length(a, b)); } W(ans); } int main() { // freopen("in.in", "r", stdin); readin(); dfs1(1, 1, 0); dfs2(1, 1); work(); flush(); return 0; } 

这篇关于BJ模拟(2) D2T3 路径规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/330348

相关文章

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

VSCode设置python SDK路径的实现步骤

《VSCode设置pythonSDK路径的实现步骤》本文主要介绍了VSCode设置pythonSDK路径的实现步骤,包括命令面板切换、settings.json配置、环境变量及虚拟环境处理,具有一定... 目录一、通过命令面板快速切换(推荐方法)二、通过 settings.json 配置(项目级/全局)三、

使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)

《使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)》字体设计和矢量图形处理是编程中一个有趣且实用的领域,通过Python的matplotlib库,我们可以轻松将字体轮廓... 目录背景知识字体轮廓的表示实现步骤1. 安装依赖库2. 准备数据3. 解析路径指令4. 绘制图形关键

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析

如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)

《如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)》:本文主要介绍如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)问题,具有很好的参考价值,希望对大家有所帮助,如有... 目录先在你打算存放的地方建四个文件夹更改这四个路径就可以修改默认虚拟内存分页js文件的位置接下来从高级-

Python模拟串口通信的示例详解

《Python模拟串口通信的示例详解》pySerial是Python中用于操作串口的第三方模块,它支持Windows、Linux、OSX、BSD等多个平台,下面我们就来看看Python如何使用pySe... 目录1.win 下载虚www.chinasem.cn拟串口2、确定串口号3、配置串口4、串口通信示例5

一文详解如何查看本地MySQL的安装路径

《一文详解如何查看本地MySQL的安装路径》本地安装MySQL对于初学者或者开发人员来说是一项基础技能,但在安装过程中可能会遇到各种问题,:本文主要介绍如何查看本地MySQL安装路径的相关资料,需... 目录1. 如何查看本地mysql的安装路径1.1. 方法1:通过查询本地服务1.2. 方法2:通过MyS

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

使用Python实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓