【NOI 2018】归程(Kruskal重构树)

题面在这里就不放了。

同步赛在做这个题的时候,心里有点纠结,很容易想到离线的做法,将边和询问一起按水位线排序,模拟水位下降,维护当前的各个联通块中距离$1$最近的距离,每次遇到询问时输出所在联通块的信息。

离线的思路对满分做法有一定的启发性,很容易想到将并查集持久化一下就能支持在线了。

但是这个是两个$log$的,有卡常的风险也不是很方便写。

当时思考了一下就快速写完离线做法就去做其他题了。

对于这道题,有一个更好的做法:Kruskal重构树。

事实上如果你了解这个东西,那你就能很快的给出解,那仅此以这道题作为学习Kruskal重构树的例子。

先给出一个经典的模型:

  • 给定一张无向图,每次询问两点之间所有简单路径中最大边权的最小值。

一个常规的做法就是建出最小生成树,答案就是树上路径的最大边权,正确性显然。

当然也可以用我们要讲的Kruskal重构树来解决,算法虽不同,思想类似。

Kruskal中我们连接两个联通块(子树)时直接用一条边将对应的两个点相连,但在Kruskal重构树中,我们先建一个虚点作为两个子树的树上父亲,让两个联通块分别与该点相连,注意的是要维护并查集合并时的有序性。

我们称新建的虚点为方点,代表了原图中的一条边,原图中的点为圆点,则该树有一些优雅的性质:

  1. 这是一颗二叉树,并且相当于一个堆,因为边是有顺序合并的。
  2. 最小生成树上路径的边权信息转化成了点权信息。

那么回顾刚刚的那个模型,每个询问就相当于回答Kruskal重构树上两点$lca$的权值。

 

最后在回来看这道题,就显得十分轻松了。

我们把每条边按照水位线从高到低依次插入,可以发现每次规定一个水位下限,车子能走的范围对应了Kruskal重构树上的一棵子树,那么每次只要倍增找到最紧的那个限制的点就可以了。

  1 #include <cstdio>
  2 #include <queue>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 typedef long long LL;
  7 const int N = 600005, INF = 2e9 + 7, LOG = 21;
  8 
  9 int tc, n, m, Qi, k, s;
 10 int dis[N], flg[N], val[N], mdi[N], gr[LOG][N];
 11 std::priority_queue<std::pair<int, int> > Q;
 12 
 13 inline void Read(int &x) {
 14     x = 0; static char c;
 15     for (c = getchar(); c < '0' || c > '9'; c = getchar());
 16     for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
 17 }
 18 
 19 struct Edge {
 20     int u, v, a;
 21     inline friend bool operator < (Edge a, Edge b) {
 22         return a.a > b.a;
 23     }
 24 } e[N];
 25 
 26 int yun, las[N], to[N << 1], pre[N << 1], wi[N << 1];
 27 inline void Add(int a, int b, int c = 0) {
 28     to[++yun] = b; wi[yun] = c; pre[yun] = las[a]; las[a] = yun;
 29 }
 30 void Gragh_clear() {
 31     memset(gr, 0, sizeof gr);
 32     memset(las, 0, sizeof las);
 33     yun = 0;
 34 }
 35 
 36 namespace DSU {
 37     int fa[N];
 38     void Init() {
 39         for (int i = 1; i <= n + m; ++i) {
 40             fa[i] = i;
 41             if (i <= n) mdi[i] = dis[i], val[i] = -1;
 42         }
 43     }
 44     int Seek(int x) {
 45         return (x == fa[x])? (x) : (fa[x] = Seek(fa[x]));
 46     }
 47     void Merge(int x, int y) {
 48         fa[Seek(y)] = x;
 49     }
 50 }
 51 
 52 void Dij() {
 53     for (int i = 1; i <= n; ++i) {
 54         dis[i] = INF; flg[i] = 0;
 55     }
 56     dis[1] = 0;
 57     Q.push(std::make_pair(0, 1));
 58     for (; !Q.empty(); ) {
 59         int x = Q.top().second; Q.pop();
 60         if (flg[x]) continue;
 61         flg[x] = 1;
 62         for (int i = las[x]; i; i = pre[i]) {
 63             if (dis[to[i]] > dis[x] + wi[i]) {
 64                 dis[to[i]] = dis[x] + wi[i];
 65                 Q.push(std::make_pair(-dis[to[i]], to[i]));
 66             }
 67         }
 68     }
 69 }
 70 
 71 int main() {
 72     freopen("return.in", "r", stdin);
 73     freopen("return.out", "w", stdout);
 74     
 75     scanf("%d", &tc);
 76     for (; tc; --tc) {
 77         scanf("%d%d", &n, &m);
 78         Gragh_clear();
 79         for (int i = 1, x, y, a, l; i <= m; ++i) {
 80             //scanf("%d%d%d%d", &x, &y, &l, &a);
 81             Read(x); Read(y); Read(l); Read(a);
 82             Add(x, y, l); Add(y, x, l);
 83             e[i] = (Edge) { x, y, a };
 84         }
 85         Dij(); DSU::Init();
 86         
 87         std::sort(e + 1, e + 1 + m);
 88         for (int i = 1; i <= m; ++i) {
 89             int x = DSU::Seek(e[i].u), y = DSU::Seek(e[i].v);
 90             if (x == y) continue;
 91             val[i + n] = e[i].a;
 92             mdi[i + n] = std::min(mdi[x], mdi[y]);
 93             DSU::Merge(i + n, x); DSU::Merge(i + n, y);
 94             gr[0][x] = gr[0][y] = i + n;
 95         }
 96         
 97         for (int i = 1; i < LOG; ++i) {
 98             for (int j = 1; j <= n + m; ++j) {
 99                 if (gr[i - 1][j]) gr[i][j] = gr[i - 1][gr[i - 1][j]];
100             }
101         }
102         
103         scanf("%d%d%d", &Qi, &k, &s);
104         for (int x, a, lans = 0; Qi; --Qi) {
105             //scanf("%d%d", &x, &a);
106             Read(x); Read(a);
107             x = (x + (LL) k * lans - 1) % n + 1;
108             a = (a + (LL) k * lans) % (s + 1);
109             for (int i = LOG - 1; ~i; --i) {
110                 if (gr[i][x] && val[gr[i][x]] > a) x = gr[i][x];
111             }
112             printf("%d\n", mdi[x]);
113             lans = mdi[x];
114         }
115     }
116     
117     return 0;
118 }
View Code

 

$\bigodot$技巧&套路:

  • kruskal重构树的构建,最小生成树上最值问题的再探。

转载于:https://www.cnblogs.com/Dance-Of-Faith/p/9333015.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

latex大括号 多行公式_如何快速入门 LaTeX,在 XMind 2020 中轻松输入方程。

数学方程输入对于很多理工科朋友来说是一件让人头疼的事情。不仅是数学方程本身就纷繁复杂花样百出&#xff0c;各种输入语法更是劝退无数人。然而很多看似复杂的东西其实并非如想象中的难&#xff0c;抓住本质即可快速入门。今天和大家分享下如何快速入门 LaTeX&#xff0c;在…

全国计算机等级考试题库二级C操作题100套(第08套)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

部署及配置Lync Server 2013 监控功能

在上面一篇文章中我们已经部署了存档功能&#xff0c;并且在标准版环境搭建了一台SQLServer服务器作为后端数据库服务器&#xff0c;有了这台服务器我们可以做什么呢&#xff1f;存档&#xff0c;当然还有监控&#xff0c;以及整个CMS。当然这都是一步一步演变的&#xff0c;并…

mysql 客户服务号获取_《MySQL排错指南》——1.4 获取查询信息-阿里云开发者社区...

本节书摘来自异步社区出版社《MySQL排错指南》一书中的第1章&#xff0c;第1.4节&#xff0c;作者&#xff1a;【美】Sveta Smirnova(斯维特 斯米尔诺娃)&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。1.4 获取查询信息正如前一节看到的一样&#xff0c;数…

基于交换芯片的五元组的PCL规则过滤功能

2019独角兽企业重金招聘Python工程师标准>>> 基于交换芯片的五元组的PCL规则过滤功能作者: 韩大卫吉林师范大学2012.12.10Not Approved by Document Control Review Copy Only基于Marvell 98DX51xx/81xx交换芯片的五元组等的策略规则(PCL)过滤功能.现将部分的功能的…

python docx 合并文档 图片_不再为处理PDF烦恼,python处理操作PDF全攻略

本篇聊下Python对pdf的各种操作&#xff0c;包含pdf转word&#xff0c;pdf转图片&#xff0c;pdf翻转&#xff0c;加密&#xff0c;加水印等。pdf转换word文档 保留格式pdf转换为word文档&#xff0c;被大众经常使用的是纯Python库pdfminer和python-docx搭配使用&#xff0c;不…

windows server 2012 初安装体验

昨天晚上的windows server 2012 已时行 了发布了&#xff0c;为之在之前我已进行了下载测试安装&#xff0c;本来晚间想用来在虚拟机下进行安装VM-tool工具的&#xff0c;但是却因种种原因没有成功&#xff0c;为之补一下前面没有安装的过程截图。 进入下载页后&#xff0c;下载…

安卓APP_ 控件(1)—— TextView

摘自&#xff1a;安卓APP_ 控件&#xff08;1&#xff09;—— TextView 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-28 21:53:49 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115283233 本文为学习笔记&#xff0c;是安卓APP学习的…

用python做数据分析pdf_利用python进行数据分析pdf

利用python进行数据分析pdf微盘下载&#xff01;《利用python进行数据分析》利用Python实现数据密集型应用由浅入深帮助读者解决数据分析问题~适合刚刚接触Python的分析人员以及刚刚接触科学计算的Python程序员。利用python进行数据分析简介&#xff1a; 还在苦苦寻觅用Python控…

安卓APP_ 控件(2)—— Button

摘自&#xff1a;安卓APP_ 控件&#xff08;2&#xff09;—— Button 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-29 14:20:54 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115290501 开篇&#xff1a;安卓APP_ 控件&#xff08;1…

安卓APP_ 控件(3)—— EditText

摘自&#xff1a;安卓APP_ 控件&#xff08;3&#xff09;—— EditText 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-03-29 18:43:40 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115305883 开篇&#xff1a;安卓APP_ 控件&#xff08…

python做游戏怎么实现窗口_python和py游戏窗口类

你在draw_sprite()中有事件循环&#xff0c;所以它一直运行到游戏结束&#xff0c;window.set_background永远不会执行。在您的代码构造不正确。在我试着更正它&#xff0c;稍后再发送代码。在编辑&#xff1a;如何组织代码的简单示例。在现在它在一个文件中。在Pygame中总是一…

如何使得账户密码永不过期

如何使得账户密码永不过期 原文:如何使得账户密码永不过期可以通过以下vbs脚本做的使得账户密码永不过期 dim users获取所有用户set users getobject("winmgmts:{impersonationlevelimpersonate}").instancesof("win32_useraccount")for each user in use…

怎么下载并安装python_怎么下载官网python并安装

怎么下载官网python并安装&#xff1f;百度搜索Python官网。看到上图显示官网的没&#xff0c;点击进入。把鼠标移到downloads上&#xff0c;然后看到下拉选项&#xff0c;点击Windows。然后看到如下界面。这么多的安装包&#xff0c;该选那个呢。下图画圈的是版本号&#xff0…

匿名函数python_基于python内置函数与匿名函数详解

内置函数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() divmod() id() object() sorted() ascii() enumerate() input() oct() staticmethod() bin() eval() int() open() str() bool() exec() isinstance() pow() super()…

ASP.NET AJAX(服务器回调)

如果只用纯粹的 js &#xff0c;你必须弥补 ASP.NET 服务器端抽象和有限的 HTML DOM 之间的鸿沟&#xff0c;这不简单&#xff0c;没有 VS 的智能提示和调试工具&#xff0c;编写无错的代码和诊断错误都非常困难。由于各种突发事件及实现的差异&#xff0c;编写能够在所有现代浏…

git版本回退命令_Git学习版本回退和管理文件的修改及删除操作

版本回退前面我们成功的提交了一次mygit.txt&#xff0c;下面咱对它进行修改&#xff0c;内容如下&#xff1a;Hello GitGit is so easy.然后用git status来跟踪该文件的状态&#xff1a;可以看到hellogit.txt已经被修改过了&#xff0c;到底这次修改的内容与上次的内容有什么不…

node 版本升级_Node-RED: 自动化事件触发工具的安装与介绍

Node-RED 介绍Node-RED 是一种基于流程的编程工具由 IBM 的新兴技术服务团队原创开发Node-RED 是一种事件触发工具&#xff0c;和 StackStorm 类似, 可以归类为上层的自动化工具&#xff0c;可以用来触发与之相对应的下层自动化工具&#xff0c;比如 ansible&#xff0c;来更加…

python处理mysql数据结构_python环境下使用mysql数据及数据结构和二叉树算法(图)...

python环境下使用mysql数据及数据结构和二叉树算法(图)&#xff1a;1 python环境下使用mysql2使用的是 pymysql库3 开始-->创建connection-->获取cursor-->操作-->关闭cursor->关闭connection->结束45 代码框架6 import pymysql.cursors7 ###连接数据库8 con…

大数据工作流_大数据和人工智能时代下的数字化工作流

点击上方“Bentley软件”可以订阅哦本文作者Bentley 软件公司高级技术经理赵顺耐大数据、人工智能以及与之相伴相生的物联网已经成为现代社会的运行方式&#xff0c;信息技术的急速发展&#xff0c;和数据量爆炸式增长&#xff0c;改变了整个社会传统的运行方式。人类与信息技术…