洛谷 P1491 集合位置

题意

给定一张 n n n m m m 边的无向图,第 i i i 个点坐标为 ( x i , y i ) (x_i,y_i) (xi,yi),求 1 → n 1 \to n 1n非严格次短路(不允许重复经过点和边)。

思路

我们采用删边的思想,先跑一遍最短路,记录路径,然后依次删掉最短路上每条边,分别跑一遍最短路,再取个最小值即可。

为什么这是正确的呢?首先,次短路至少有一条边不属于最短路。其次,我们不用枚举不在最短路上的边,因为删这些边对最短路没有影响。

至于如何删边,不需要直接在邻接表中找到后再删,这没必要,还会超时,只需要在跑最短路的时候,传入两个参数,分别是要删掉的边的两个端点,只要当前边相连的是这两个点,就直接忽略掉(注意无向图)。

typedef double real;
typedef pair<int, double> PID;
typedef pair<double, int> PDI;
const real INF = 1e20;

struct Graph{
	int n;
	vector<vector<PID>> G;
	vector<real> dis;
	vector<int> pre;
	vector<bool> vis;
	
	Graph(int _n): n(_n){
		G.resize(n);
	}
	
	// Add an undirected edge <u, v> to the graph with edge weight `w`。
	void insert(int u, int v, real w){
		G[u].push_back({v, w});
		G[v].push_back({u, w});
	}
	
	// Starting from s, run the shortest path, ignoring edges (du, dv).
	// If (du, dv) = (-1, -1), then no edge will be deleted and the path will be recorded in `pre`.
	void dij(int s, int du = -1, int dv = -1){
		dis.assign(n, INF);
		vis.assign(n, false);
		if(du == -1 && dv == -1) pre.assign(n, -1);
		
		priority_queue<PDI, vector<PDI>, greater<PDI>> q;
		dis[s] = 0.;
		q.push({0., s});
		
		while(q.size()){
			int u = q.top().second;
			q.pop();
			
			if(vis[u]) continue;
			vis[u] = true;

			for(auto &edge: G[u]){
				int v = edge.first;
				real w = edge.second;
				if((du == u && dv == v) || (du == v && dv == u)) continue;
				if(dis[v] > dis[u] + w){
					dis[v] = dis[u] + w;
					q.push({dis[v], v});
					if(du == -1 && dv == -1) pre[v] = u;
				}
			}
		}
	}
};

代码

#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
#define int long long

typedef double real;
typedef pair<int, double> PID;
typedef pair<double, int> PDI;
const real INF = 1e20;

struct Graph{
	int n;
	vector<vector<PID>> G;
	vector<real> dis;
	vector<int> pre;
	vector<bool> vis;
	
	Graph(int _n): n(_n){
		G.resize(n);
	}
	
	void insert(int u, int v, real w){
		G[u].push_back({v, w});
		G[v].push_back({u, w});
	}
	
	void dij(int s, int du = -1, int dv = -1){
		dis.assign(n, INF);
		vis.assign(n, false);
		if(du == -1 && dv == -1) pre.assign(n, -1);
		
		priority_queue<PDI, vector<PDI>, greater<PDI>> q;
		dis[s] = 0.;
		q.push({0., s});
		
		while(q.size()){
			int u = q.top().second;
			q.pop();
			
			if(vis[u]) continue;
			vis[u] = true;

			for(auto &edge: G[u]){
				int v = edge.first;
				real w = edge.second;
				if((du == u && dv == v) || (du == v && dv == u)) continue;
				if(dis[v] > dis[u] + w){
					dis[v] = dis[u] + w;
					q.push({dis[v], v});
					if(du == -1 && dv == -1) pre[v] = u;
				}
			}
		}
	}
};

real dist(real x1, real y1, real x2, real y2){
	real p = x1 - x2, q = y1 - y2;
	return sqrt(p * p + q * q);
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int n, m;
	cin >> n >> m;
	
	vector<real> x(n), y(n);
	Graph G(n);
	for(int i = 0; i < n; i++) cin >> x[i] >> y[i];
	for(int i = 0, u, v; i < m; i++){
		cin >> u >> v;
		u--, v--;
		
		real w = dist(x[u], y[u], x[v], y[v]);
		G.insert(u, v, w);
	}
	
	G.dij(0);
	
	real ans = INF;
	for(int i = n - 1; i; i = G.pre[i]){
		G.dij(0, i, G.pre[i]);
		ans = min(ans, G.dis.back());
	}
	
	if(ans >= INF) printf("-1\n");
	else printf("%.2lf\n", ans);
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务器本地部署文件服务器minio

minio类似于阿里云的OSS&#xff0c;为不方便把图、文、日志等形式的文件保存在公有云上的&#xff0c;可以在自己的服务器上部署文件服务器 看过本人前几个文章的&#xff0c;使用docker就会很快上手部署&#xff0c;直接上所有代码 #添加镜像 docker search minio docker p…

jvm 03 JVM的运行时数据区域 ,(类常量池,运行时常量池,字符串常量池这个三个的区别),操作系统内存模型JMM和JVM的内存模型联系

方法区在jdk8后&#xff0c;改成元空间 JVM内存模型&#xff1a; JMM 主内存&#xff1a;本地方法区和堆 工作内存&#xff1a;私有的工作栈 其实一个JVM内存模型&#xff08;主要就是运行时数据区域&#xff09;一个Java进程的JMM&#xff0c;工作内存JVM中线程的内存区域…

关于umjs的主题切换实现

注意本文写作日期2024年7月7日&#xff0c;我目前是最新版本的 注意&#xff1a;该功能仅 antd v5 可用 最后目标实现 先说一下&#xff0c;umijs布局默认是内置ant-design/pro-layout布局写的 看一下官网ProLayout - 高级布局和布局与菜单 直接在app.tsx加入以下&#xff…

Git管理源代码、git简介,工作区、暂存区和仓库区,git远程仓库github,创建远程仓库、配置SSH,克隆项目

学习目标 能够说出git的作用和管理源代码的特点能够如何创建git仓库并添加忽略文件能够使用add、commit、push、pull等命令实现源代码管理能够使用github远程仓库托管源代码能够说出代码冲突原因和解决办法能够说出 git 标签的作用能够使用使用git实现分支创建&#xff0c;合并…

磐维2.0数据库日常维护

磐维数据库简介 “中国移动磐维数据库”&#xff08;ChinaMobileDB&#xff09;&#xff0c;简称“磐维数据库”&#xff08;PanWeiDB&#xff09;。是中国移动信息技术中心首个基于中国本土开源数据库打造的面向ICT基础设施的自研数据库产品。 其产品内核能力基于华为 OpenG…

pyrender 离线渲染包安装教程

pyrender 离线渲染包安装教程 安装 安装 官方安装教程:https://pyrender.readthedocs.io/en/latest/install/index.html#installmesa 首先 pip install pyrenderclang6.0安装 下载地址:https://releases.llvm.org/download.html#6.0.0 注意下好是叫&#xff1a;clangllvm-6…

L04_MySQL知识图谱

这些知识点你都掌握了吗&#xff1f;大家可以对着问题看下自己掌握程度如何&#xff1f;对于没掌握的知识点&#xff0c;大家自行网上搜索&#xff0c;都会有对应答案&#xff0c;本文不做知识点详细说明&#xff0c;只做简要文字或图示引导。 1 基础 1.1内部组件结构 1.2 数据…

尚品汇-(十四)

&#xff08;1&#xff09;提交git 商品后台管理到此已经完成&#xff0c;我们可以把项目提交到公共的环境&#xff0c;原来使用svn&#xff0c;现在使用git 首先在本地创建ssh key&#xff1b; 命令&#xff1a;ssh-keygen -t rsa -C "your_emailyouremail.com" I…

用kimi实现一键实体识别与关系抽取

实体识别与关系抽取是自然语言处理&#xff08;NLP&#xff09;中的两个重要任务&#xff0c;通常被视为知识图谱构建的基础技术。 实体识别&#xff08;Named Entity Recognition, NER&#xff09;&#xff1a; 实体识别的目标是从文本中识别出具有特定意义的实体&#xff0…

动手学深度学习(Pytorch版)代码实践 -循环神经网络- 56门控循环单元(`GRU`)

56门控循环单元&#xff08;GRU&#xff09; 我们讨论了如何在循环神经网络中计算梯度&#xff0c; 以及矩阵连续乘积可以导致梯度消失或梯度爆炸的问题。 下面我们简单思考一下这种梯度异常在实践中的意义&#xff1a; 我们可能会遇到这样的情况&#xff1a;早期观测值对预测…

Nacos2.X源码分析:服务注册、服务发现流程

文章目录 Nacos2.1.X源码源码下载服务注册NacosClient端NacosServer端 服务发现NacosClient端NacosServer端 Nacos2.1.X源码 源码下载 源码下载地址 服务注册 官方文档&#xff0c;对于NamingService接口服务注册方法的说明 Nacos2.X 服务注册总流程图 NacosClient端 一个…

华为OSPF配置DR和BDR与指定DR

基础配置 <Huawei>sys #进入配置模式 Enter system view, return user view with CtrlZ. [Huawei]un in en #关闭报文弹窗 Info: Information center is disabled. [Huawei]sys R1 #设备名更改为R1 [R1]int g0/0/0 …

智能物联网鱼缸

硬件部分及接线图 工具 继电器、开发板、物联网os、云平台 微信小程序 结构&#xff1a;images、pages两个为主体。 标题头部分 <view class"container"> <view class"head_box"> <image src"/images/面性鱼缸.png"><…

【Java】详解String类中的各种方法

创建字符串 常见的创建字符串的三种方式&#xff1a; // 方式一 String str "hello world"; // 方式二 String str2 new String("hello world"); // 方式三 char[] array {a, b, c}; String str3 new String(array); "hello" 这样的字符串字…

昇思学习打卡-8-FCN图像语义分割

目录 FCN介绍FCN所用的技术训练数据的可视化模型训练模型推理FCN的优点和不足优点不足 FCN介绍 FCN主要用于图像分割领域&#xff0c;是一种端到端的分割方法&#xff0c;是深度学习应用在图像语义分割的开山之作。通过进行像素级的预测直接得出与原图大小相等的label map。因…

3-4 优化器和学习率

3-4 优化器和学习率 主目录点这里 优化器是机器学习和深度学习模型训练过程中用于调整模型参数的方法。它的主要目标是通过最小化损失函数来找到模型参数的最优值&#xff0c;从而提升模型的性能。 在深度学习中&#xff0c;优化器使用反向传播算法计算损失函数相对于模型参数…

C++ 函数高级——函数的占位参数

C中函数的形参列表里可以有占位参数&#xff0c;用来做占位&#xff0c;调用函数时必须填补改位置 语法&#xff1a; 返回值类型 函数名&#xff08;数据类型&#xff09;{ } 在现阶段函数的占位参数存在意义不大&#xff0c;但是后面的课程中会用到该技术 示例&#xff1a;…

TypeScript:5分钟上手创建一个简单的Web应用

一、练习TypeScript实例 1.1 在src目录里创建greeter.ts greeter.ts文件代码 // https://www.tslang.cn/docs/handbook/typescript-in-5-minutes.html // 格式化快捷键&#xff1a;https://blog.csdn.net/Dontla/article/details/130255699 function greeter(name: string) …

Windows电脑下载、安装VS Code的方法

本文介绍Visual Studio Code&#xff08;VS Code&#xff09;软件在Windows操作系统电脑中的下载、安装、运行方法。 Visual Studio Code&#xff08;简称VS Code&#xff09;是一款由微软开发的免费、开源的源代码编辑器&#xff0c;支持跨平台使用&#xff0c;可在Windows、m…

采煤机作业3D虚拟仿真教学线上展示增强应急培训效果

在化工行业的生产现场&#xff0c;安全永远是首要之务。为了加强从业人员的应急响应能力和危机管理能力&#xff0c;纷纷引入化工行业工艺VR模拟培训&#xff0c;让应急演练更加生动、高效。 化工行业工艺VR模拟培训软件基于真实的厂区环境&#xff0c;精确还原了各类事件场景和…