题目大意:初始给定 N 个点,支持三种操作:两点之间连边;一个点与一个连续区间编号的点之间连边;一个连续区间内的点和一个点连边,求执行 N 次操作之后的单源最短路。

题解:学会了线段树优化建图。
发现若暴力进行连边,时间和空间都会被卡到 \(O(n^2)\),直接起飞。
发现连边的点的编号是连续的,结合线段树可以维护连续区间信息的思想,就产生了线段树优化建图的方法。
在初始的 N 个节点的基础上建立两棵线段树,分别表示入树和出树,其中入树的上的各个节点允许单个节点的连接;出树上的节点允许连接单个节点。对于入树中的每个节点来说,需要连一条边权为 0 的有向边到它的两个儿子,表示若有节点连向父节点,那么一定也连向了儿子节点;对于出树上的每个节点来说,需要连一条边权为 0 的有向边到它的父节点,表示若当前节点可以连向某个节点,那么其子节点也一定可以走到这个节点。
时空复杂度分析:空间为两棵线段树的空间减去一份叶子节点的大小,即:\(3 * n\),时间复杂度为 \(elog^2v\),其中 e 是边的条数,v 是节点的个数。

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;struct edge {int to;LL w;edge(int x = -1, int y = -1) {to = x, w = y;}
};struct segtree {#define ls(o) tree[o].lc#define rs(o) tree[o].rcstruct node {int lc, rc;};vector<node> tree;int tot, rootin, rootout;segtree(int n, vector<vector<edge>> &adj) {tot = n;tree.resize(3 * n);buildin(rootin, 1, n, adj);buildout(rootout, 1, n, adj);}void buildin(int &o, int l, int r, vector<vector<edge>> &adj) {if (l == r) {o = l;return;}o = ++tot;int mid = l + r >> 1;buildin(ls(o), l, mid, adj);buildin(rs(o), mid + 1, r, adj);adj[o].emplace_back(ls(o), 0);adj[o].emplace_back(rs(o), 0);}void buildout(int &o, int l, int r, vector<vector<edge>> &adj) {if (l == r) {o = l;return;}o = ++tot;int mid = l + r >> 1;buildout(ls(o), l, mid, adj);buildout(rs(o), mid + 1, r, adj);adj[ls(o)].emplace_back(o, 0);adj[rs(o)].emplace_back(o, 0);}void link(int o, int l, int r, int x, int y, int u, int w, int opt, vector<vector<edge>> &adj) {// opt 2 -> in  3 -> outif (l == x && r == y) {opt == 2 ? adj[u].emplace_back(o, w) : adj[o].emplace_back(u, w);return;}int mid = l + r >> 1;if (y <= mid) {link(ls(o), l, mid, x, y, u, w, opt, adj);} else if (x > mid) {link(rs(o), mid + 1, r, x, y, u, w, opt, adj);} else {link(ls(o), l, mid, x, mid, u, w, opt, adj);link(rs(o), mid + 1, r, mid + 1, y, u, w, opt, adj);}}
};int main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int n, m, s;cin >> n >> m >> s;vector<vector<edge>> adj(3 * n);segtree t(n, adj);while (m--) {int opt;cin >> opt;if (opt == 1) {int u, v, w;cin >> u >> v >> w;adj[u].emplace_back(v, w);} else {int u, l, r, w;cin >> u >> l >> r >> w;t.link(opt == 2 ? t.rootin : t.rootout, 1, n, l, r, u, w, opt, adj);}}vector<LL> d(3 * n, 1e18);vector<bool> expand(3 * n);priority_queue<pair<LL, int>> q;auto dijkstra = [&]() {d[s] = 0, q.push(make_pair(0, s));while (!q.empty()) {int u = q.top().second;q.pop();if (expand[u] == 1) {continue;}expand[u] = 1;for (auto e : adj[u]) {int v = e.to, w = e.w;if (d[v] > d[u] + w) {d[v] = d[u] + w;q.push(make_pair(-d[v], v));}}}};dijkstra();for (int i = 1; i <= n; i++) {if (d[i] == 1e18) {cout << "-1" << " ";} else {cout << d[i] << " ";}}return 0;
}

转载于:https://www.cnblogs.com/wzj-xhjbk/p/11528900.html

【CF786B】Legacy相关推荐

  1. Android启动过程深入解析【转】

    转自:http://www.open-open.com/lib/view/open1403250347934.html 当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么 ...

  2. 【STM32】低功耗相关函数和类型

    00. 目录 文章目录 00. 目录 01. 概述 02. 相关类型 03. 相关函数 04. 结构体封装 05. 预留 06. 附录 07. 声明 01. 概述 很多单片机都有低功耗模式,STM32 ...

  3. 【STM32】GPIO功能复用

    00. 目录 文章目录 00. 目录 01. GPIO复用概述 02. 寄存器描述 03. 类型 04. 函数 05. 参考示例 06. 附录 07. 声明 01. GPIO复用概述 STM32F4 ...

  4. 【STM32】GPIO相关函数和类型

    00. 目录 文章目录 00. 目录 01. GPIO固件库概述 02. GPIO相关类型 03. GPIO相关宏 04. GPIO相关函数 05. GPIO其它相关 06. 附录 07. 声明 01 ...

  5. 【Linux】一步一步学Linux——telinit命令(144)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 设置当前系统的运行等级 说明: This is a leg ...

  6. 【Maven】Maven POM配置详解

    就像web项目的核心是web.xml一样,Maven项目的核心是pom.xml,POM(project object model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,如何声明依赖 ...

  7. 【Ogre-windows】环境配置

    前言 由于工程原因, 学习一下Ogre面向对象图形渲染开源引擎, 慢慢爬坑吧.首先还是环境的配置问题哎. 其实最重要的是要预先编译三方库, 虽然官方说可以自动编译, 但是在自己电脑上还是出现了无法解析 ...

  8. [DIV/CSS] 【译】60个有用CSS代码片段

    2019独角兽企业重金招聘Python工程师标准>>> 1.垂直对齐 如果你用CSS,则你会有困惑:我该怎么垂直对齐容器中的元素?现在,利用CSS3的Transform,可以很优雅的 ...

  9. win8服务器无法安装win7系统安装,win8怎么安装win7 win8改win7教程详解【图文】

    继win7系统后,微软又推出了win8.win8.1以及win10系统,每个系统在原来的版本上都有了更改和创新.大家都知道,人是一种容易习惯的动物.很多人在使用了win7之后,更换到win8系统会很不 ...

最新文章

  1. 一套使用注入和Hook技术托管入口函数的方案
  2. python 浏览器显示本地文件夹_从浏览器中打开本地文件文件夹
  3. 余切表示matlab,matlab中 正弦余弦正切余切的画法 以及For while的用法
  4. flink的CEP调研与使用
  5. hive 多用户访问模注意问题
  6. 小C语言程序----词法分析程序输出单词
  7. Exchange 2013SP1和O365混合部署系列二
  8. HDU各种比赛题题解(一)
  9. 倾囊传授DELL主板BIOS设置
  10. LR之Java Vuser
  11. snownlp抛出错误_请教大家有关SnowNLP分词、词性标注、情感分析的问题
  12. Delphi FastReport组件下载,包含多个版本,自己选择
  13. 穷查理宝典_穷查理宝典
  14. 十大新兴编程语言_十大编程语言
  15. 关于#!/bin/bash
  16. linux 儒略日时间计算,儒略日(儒略日 在线计算器)
  17. mysql数据库的语句
  18. Creator新手引导 | 限制只能点击一个按钮 | 文字打字机效果
  19. PowerPoint 中缺少think-cell 加载项丨解决方案丨使用教程
  20. php字符串操作整理,PHP 字符串操作整理

热门文章

  1. C#——if 和 Switch 的区别,与在内存中的占有量
  2. 风水 第一节 环境感受简谈
  3. “炒房团”攻占元宇宙,有人2732万买入一块虚拟土地,林俊杰也花78万入手了
  4. 电商项目的介绍及其框架搭建
  5. USB Type-C学习点滴
  6. 为什么自己干了这么多活,最后功劳都是别人的?
  7. Map集合中两个重要的取值方法---keySet()和entrySet()
  8. cf - 922C - Cave Painting ( 思维 + 数学 )
  9. Java 实现双色球的彩票功能。规则:从33个红球中随机选择不重复的6个数,从16个蓝球中随机选择1个组成一注彩票。可以选择买多注。
  10. 硬盘分区表的数据结构