【图论经典题目讲解】CF786B - Legacy 一道线段树优化建图的经典题目

news2024/11/25 7:44:10

C F 786 B − L e g a c y \mathrm{CF786B - Legacy} CF786BLegacy

D e s c r i p t i o n \mathrm{Description} Description

给定 1 1 1 n n n 个点的有向图,初始没有边,接下来有 q q q 次操作,形式如下:

  • 1 u v w 表示从 u u u v v v 连接 1 1 1 条长度为 w w w 的有向边
  • 2 u l r w 表示从 u u u i i i i ∈ [ l , r ] i\in [l,r] i[l,r])连接 1 1 1 条长度为 w w w 的有向边
  • 3 u l r w 表示从 i i i i ∈ [ l , r ] i\in [l,r] i[l,r])向 u u u 连接 1 1 1 条长度为 w w w 的有向边

输出从 S S S 点到 i i i 点( i ∈ [ 1 , n ] i\in [1,n] i[1,n])的最短路长度。

S o l u t i o n \mathrm{Solution} Solution

观察可知,最多会建立 1 0 5 × 1 0 5 = 1 0 10 10^5\times 10^5 = 10^{10} 105×105=1010 条边,故必定超时。

此时,需要使用 线段树优化建图,这里展开简单说一下:

对于 1 1 1 棵存储点为 1 ∼ 4 1\sim 4 14 的线段树,形式如下:

image-20240215212043652

如果当前为 2 2 2 操作,且为 1 ∼ 3 1\sim 3 13 每个点连向 4 4 4,权值为 10 10 10,操作如下所示:

image-20240215212212466

即,将区间 1 ∼ 2 1\sim 2 12 3 ∼ 3 3\sim 3 33 连向 4 4 4 即可,不过此时发现,图中为有向图,而现在是无向图所以我们要对于图中的每一条边标记方向和权值(这里线段树就是一张图,叶子节点就是我们的 1 ∼ n 1\sim n 1n 节点)

image-20240215212641895

其中,为何线段树上的边方向都为向父亲节点?那是因为 1 1 1 2 2 2 号点只有这样才能顺着边走到 4 4 4 号节点,对于为何权值设为 0 0 0,因为这是 1 1 1 条虚边(不存在的),不能对最短路做出任何贡献。

不过,上文是区间连节点,当是节点连区间的时候(操作 3 3 3)边都是正好反着的,所以再建 1 1 1 棵线段树即可(不过没必要真的去再建 1 1 1 棵,具体见代码)

C o d e Code Code

#include <bits/stdc++.h>
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int SIZE = 4e6 + 10, SIZE2 = 1e6 + 10;

int N, Q, S;
int h[SIZE2], e[SIZE], ne[SIZE], w[SIZE], idx;
int Id[2], Dist[SIZE2], Vis[SIZE2];
struct Segment
{
	int l, r;
	int L, R;
}Tree[SIZE2 << 2];

void add(int a, int b, int c)
{
	e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

int Build(int l, int r, int Sd, int k)
{
	if (l == r)
	{
		Tree[l] = {l, l};
		return l;
	}
	int P = ++ Id[k];
	Tree[P] = {l, r};

	int mid = l + r >> 1;
	Tree[P].L = Build(l, mid, Sd, k), Tree[P].R = Build(mid + 1, r, Sd, k);

	if (!Sd) add(Tree[P].L, P, 0), add(Tree[P].R, P, 0);
	else add(P, Tree[P].L, 0), add(P, Tree[P].R, 0);

	return P;
}

void Add(int u, int l, int r, int p, int w, int Sd)
{
	if (Tree[u].l >= l && Tree[u].r <= r)
	{
		if (!Sd) add(u, p, w);
		else add(p, u, w);
		return;
	}

	int mid = Tree[u].l + Tree[u].r >> 1;
	if (mid >= l) Add(Tree[u].L, l, r, p, w, Sd);
	if (mid < r) Add(Tree[u].R, l, r, p, w, Sd);
}

void Dijkstra(int S)
{
	memset(Dist, 0x3f, sizeof Dist);
	memset(Vis, 0, sizeof Vis);
	priority_queue<PII, vector<PII>, greater<PII>> Heap;
	Heap.push({0, S}), Dist[S] = 0;

	while (Heap.size())
	{
		auto Tmp = Heap.top();
		Heap.pop();

		int u = Tmp.second;
		if (Vis[u]) continue;
		Vis[u] = 1;

		for (int i = h[u]; ~i; i = ne[i])
		{
			int j = e[i];
			if (Dist[j] > Dist[u] + w[i])
			{
				Dist[j] = Dist[u] + w[i];
				Heap.push({Dist[j], j});
			}
		}
	}
}

signed main()
{
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	memset(h, -1, sizeof h);

	cin >> N >> Q >> S;

	if (N == 1)
	{
		cout << 0 << endl;
		return 0;
	}

	Id[0] = N;
	Build(1, N, 0, 0);
	Id[1] = Id[0];
	Build(1, N, 1, 1);

	while (Q --)
	{
		int Op, v, u, l, r, w;
		cin >> Op >> u;

		if (Op == 1)
		{
			cin >> v >> w;
			add(u, v, w);
		}
		else if (Op == 2)
		{
			cin >> l >> r >> w;
			Add(Id[0] + 1, l, r, u, w, 1);
		}
		else
		{
			cin >> l >> r >> w;
			Add(N + 1, l, r, u, w, 0);
		}
	}

	Dijkstra(S);

	for (int i = 1; i <= N; i ++)
		if (Dist[i] >= 1e18) cout << -1 << " ";
		else cout << Dist[i] << " ";

	return 0;
}

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

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

相关文章

GO和KEGG富集分析

写在前面 我们《复现SCI文章系列教程》专栏现在是免费开放&#xff0c;推出这个专栏差不多半年的时间&#xff0c;但是由于个人的精力和时间有限&#xff0c;只更新了一部分。后续的更新太慢了。因此&#xff0c;最终考虑后还是免费开放吧&#xff0c;反正不是什么那么神秘的东…

关于数据结构的定义以及基本的数据结构

在计算机科学中&#xff0c;数据结构是指用于组织和存储数据的方式或方法。它涉及到在计算机内存中存储、管理和操作数据的技术和原则。数据结构不仅仅是简单地存储数据&#xff0c;还可以提供高效的数据访问和操作方式&#xff0c;以满足特定的需求。 以下是每个数据结构的详细…

mkcert安装教程

1、下载 官方文档&#xff1a;https://github.com/FiloSottile/mkcert#mkcert 下载链接&#xff1a;https://github.com/FiloSottile/mkcert/releases 2、安装&#xff0c;该文件目录下打开cmd&#xff08;可以把文件复制到别的文件夹&#xff09;&#xff0c;执行命令 //命令…

开源模型应用落地-工具使用篇-向量数据库进阶(四)

一、前言 通过学习"开源模型应用落地"系列文章&#xff0c;我们成功地建立了一个完整可实施的AI交付流程。现在&#xff0c;我们要引入向量数据库&#xff0c;作为我们AI服务的二级缓存。本文将继续基于上一篇“开源模型应用落地-工具使用篇-向量数据库&#xff08;三…

FreeRTOS移植到GD32

目录 一、GD32基础工程创建&#xff1a; 1、创建如下文件夹 2、在keil5创建工程 3、在工程添加相关.c文件和头文件路径 4、实例&#xff1a;实现LED闪烁功能 二、在基础工程添加FreeRTOS&#xff1a; 1、FreeRTOS中的文件: 2、添加的源文件: 3、添加的头文件路径: 4、…

机器人常用传感器分类及一般性要求

机器人传感器的分类 传感技术是先进机器人的三大要素&#xff08;感知、决策和动作&#xff09;之一。根据用途不同&#xff0c;机器人传感器可以分为两大类&#xff1a;用于检测机器人自身状态的内部传感器和用于检测机器人相关环境参数的外部传感器。 内部传感器 内部传感…

【JavaEE】_HTML常用标签

目录 1.HTML结构 2. HTML常用标签 2.1 注释标签 2.2 标题标签&#xff1a;h1~h6 2.3 段落标签&#xff1a;p 2.4 换行标签&#xff1a;br 2.5 格式化标签 2.6 图片标签&#xff1a;img 2.7 超链接标签&#xff1a;a 2.8 表格标签 2.9 列表标签 2.10 表单标签 2.10…

航班进出港|航班进出港管理系统|基于springboot航班进出港管理系统设计与实现(源码+数据库+文档)

航班进出港管理系统目录 目录 基于springboot航班进出港管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 5、航班信息管理 &#xff08;1&#xff09; 航班信息管理 &#xff08;2&#xff09;起飞降落申请管理 &#xff08;3&#xff09;公告管理 &…

辽宁博学优晨教育科技有限公司视频剪辑培训专业之选

随着数字时代的到来&#xff0c;视频剪辑技术已成为各行各业不可或缺的一项技能。为了满足市场需求&#xff0c;辽宁博学优晨教育科技有限公司&#xff08;以下简称“博学优晨”&#xff09;推出了专业的视频剪辑培训课程&#xff0c;旨在为广大学员提供系统、高效的学习机会。…

AMD FPGA设计优化宝典笔记(4)复位桥

高亚军老师的这本书《AMD FPGA设计优化宝典》&#xff0c;他主要讲了两个东西&#xff1a; 第一个东西是代码的良好风格&#xff1b; 第二个是设计收敛等的本质。 这个书的结构是一个总论&#xff0c;加上另外的9个优化&#xff0c;包含的有&#xff1a;时钟网络、组合逻辑、触…

面试系列之《Spark》(持续更新...)

1.job&stage&task如何划分&#xff1f; job&#xff1a;应用程序中每遇到一个action算子就会划分为一个job。 stage&#xff1a;一个job任务中从后往前划分&#xff0c;分区间每产生了shuffle也就是宽依赖则划分为一个stage&#xff0c;stage这体现了spark的pipeline思…

picker选择器-年月日选择

从底部弹起的滚动选择器。支持五种选择器&#xff0c;通过mode来区分&#xff0c;分别是普通选择器&#xff0c;多列选择器&#xff0c;时间选择器&#xff0c;日期选择器&#xff0c;省市区选择器&#xff0c;默认是普通选择器。 学习一下日期选择器 平台差异说明 日期选择默…

k8s学习(RKE+k8s+rancher2.x)成长系列之简配版环境搭建(三)

3.19.切换RKE用户,并做免密登录(三台机器相互免密) su rke cd~ ssh-keygen[rke@master.ssh]$ssh-copy-id rke@slaver2 [rke@master.ssh]$ssh-copy-id rke@slaver1 [rke@master.ssh]$ssh-copy-id rke@master3.20.搭建RKE集群 为了方便理解,我们把通RKE部署的Kubernetes集群称…

浏览网页记录工具,企业如何查看员工网页浏览记录

随着信息技术的飞速发展&#xff0c;网络已成为企业日常运营和员工工作中不可或缺的一部分。然而&#xff0c;随之而来的是网络安全和员工上网行为管理的挑战。在这种情况下&#xff0c;浏览网页记录工具成为了企业监控员工上网行为的重要手段之一。 一、浏览网页记录工具的重要…

MySQL 基础知识(十)之 MySQL 架构

目录 1 MySQL 架构说明 2 连接层 3 核心业务层 3.1 查询缓存 3.2 解析器 3.3 优化器 3.4 执行器 4 存储引擎层 5 参考文档 1 MySQL 架构说明 下图是 MySQL 5.7 及其之前版本的逻辑架构示意图 MySQL 架构大致可分为以下三层&#xff1a; 连接层&#xff1a;负责跟客户…

unity学习(29)——GameInfo角色信息

1.把GameInfo.cs PlayerModel.cs Vector3.cs Vector4.cs PlayerStateConstans.cs GameState.cs依次粘到model文件夹中&#xff0c;此时项目没有错误&#xff0c;如下图所示&#xff1b; 对应处所修改的代码如下&#xff1a; case LoginProtocol.LOGIN_SRES://1 {Debug.Log(&qu…

软件工程师,AI手机元年到来,我们怎么办

概述 OPPO创始人、总裁、CEO陈明永在2024年2月18日发表了名为《开启AI手机新时代》的内部信。陈明永认为&#xff1a;“2024年是AI手机元年。未来五年&#xff0c;AI对手机行业的影响&#xff0c;完全可以比肩当年智能手机替代功能机”。他预测AI手机时代将成为继功能机、智能手…

docker jenkins 报错:script.sh.copy: 1: mvn: not found

找不到mvn,一般是没配置环境变量的问题。点开系统配置&#xff0c;设置环境变量即可

Python教程(27)——如何使用Python中的上下文管理器

当我们在编写代码时&#xff0c;经常会遇到需要管理资源的情况&#xff0c;比如打开和关闭文件&#xff0c;如果遇到了一些异常情况&#xff0c;我们需要关闭资源&#xff0c;不然会导致资源泄露&#xff0c;虽然我们可以通过手动的方式来关闭&#xff0c;但如果有多个异常情况…

(十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)

简述 操作路径如下: 作用:通过逐步增加线程数来模拟用户并发访问。配置:设置This group will start、First,wait for 、Then start、Next , add等参数。使用场景:模拟逐步增长的并发访问,观察应用程序的性能变化。优点:适用于测试应用程序在逐步增加负载下的性能表现。…