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

相关文章

利用Python把路径转为绝对路径的方法

《利用Python把路径转为绝对路径的方法》在Python中,如果你有一个相对路径并且想将其转换为绝对路径,你可以使用Path对象的resolve()方法,Path是Python标准库pathlib中... 目录1. os.path.abspath 是什么?怎么用?基本用法2. os.path.abspat

Java 单元测试之Mockito 模拟静态方法与私有方法最佳实践

《Java单元测试之Mockito模拟静态方法与私有方法最佳实践》本文将深入探讨如何使用Mockito来模拟静态方法和私有方法,结合大量实战代码示例,带你突破传统单元测试的边界,写出更彻底、更独立... 目录Mockito 简介:为什么选择它?环境准备模拟静态方法:打破“不可变”的枷锁传统困境解法一:使用M

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

SpringBoot路径映射配置的实现步骤

《SpringBoot路径映射配置的实现步骤》本文介绍了如何在SpringBoot项目中配置路径映射,使得除static目录外的资源可被访问,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一... 目录SpringBoot路径映射补:springboot 配置虚拟路径映射 @RequestMapp

浅谈MySQL的容量规划

《浅谈MySQL的容量规划》进行MySQL的容量规划是确保数据库能够在当前和未来的负载下顺利运行的重要步骤,容量规划包括评估当前资源使用情况、预测未来增长、调整配置和硬件资源等,感兴趣的可以了解一下... 目录一、评估当前资源使用情况1.1 磁盘空间使用1.2 内存使用1.3 CPU使用1.4 网络带宽二、

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

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 配置(项目级/全局)三、