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

相关文章

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

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

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象