首页 > 其他分享 >次短路问题(最短路)

次短路问题(最短路)

时间:2024-07-14 22:11:12浏览次数:8  
标签:1.0 int double 短路 问题 v1 dis

https://www.luogu.com.cn/problem/P1491


第5题     次短路问题 查看测评数据信息

平面直角坐标系中有n个点,m条边,第i个点的坐标是(x[i],y[i]),求编号为1的点到编号为n的点第二最短路线的距离(保留两位小数),如果存在多条第一短路径,则答案就是第一最短路径的长度;数据没有重边,可能有自环

输入格式

 

第一行两个数n和m

接下来n行,每行两个整数x[i],y[i]

接下来m行,每行两个整数u,v,表示u和v之间有一条路径

其中1<=n<=200,1<=m<=10000, -500<=x[i],y[i]<=500

 

输出格式

 

一行一个数(保留两位小数)

 

输入/输出例子1

输入:

3 3

0 0

1 1

0 2

1 2

1 3

2 3

 

输出:

2.83

 

样例解释

 

一般用删边法,这里采用枚举法

我们想求次短路,也就是在跑最短路的过程中加上一条边呗,转换成以下式子:

 从1到u的距离我们在第一次跑最短路的时候可以求,v到n的距离可以从n跑一遍然后求一遍,u到v的距离就单纯枚举边

注意,如果有多条最短路,得输出最短路,可以在第一次跑的时候最短路计数

#include <bits/stdc++.h>
using namespace std;
const int N=205;

struct node
{
	int v;
	double w;
	bool operator <(const node &A) const
	{
		return w>A.w;
	};
};
struct node2
{
	int u, v;
	double w;
};
int n, m, x[N], y[N], u1, v1, cnt[N], vis[N];
double dis[N], dis2[N], ans=1e9;
vector<node> a[N];
vector<node2> s;
priority_queue<node> q;
double js(int u1, int v1)
{
	double a=abs(x[u1]*1.0-x[v1]*1.0)*1.0;
	double b=abs(y[u1]*1.0-y[v1]*1.0)*1.0;
	return sqrt(a*a+b*b)*1.0;
}
void dij(int s)
{
	for (int i=0; i<=N-5; i++) dis[i]=1e9;
	memset(vis, 0, sizeof vis);
	memset(cnt, 0, sizeof cnt);
	
	dis[s]=0;
	q.push({s, 0});
	
	while (!q.empty())
	{
		int u=q.top().v;
		q.pop();
		
		if (vis[u]) continue;
		vis[u]=1;
		
		for (int i=0; i<a[u].size(); i++)
		{
			int v=a[u][i].v;
			double w=a[u][i].w;
			
			if (dis[v]==dis[u]+w) cnt[v]++;
			if (dis[v]>dis[u]+w)
			{
				cnt[v]=1;
				dis[v]=dis[u]+w;
				q.push({v, dis[v]});
			}
		}
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) scanf("%d%d", &x[i], &y[i]);
	for (int i=1; i<=m; i++)
	{
		scanf("%d%d", &u1, &v1);
		s.push_back({u1, v1, js(u1, v1)});
		a[u1].push_back({v1, js(u1, v1)});
		a[v1].push_back({u1, js(u1, v1)});	
	}
	
	dij(1);
	if (cnt[n]>1) 
	{
		printf("%.2lf", dis[n]);
		return 0;
	}
	
	for (int i=1; i<=n; i++) dis2[i]=dis[i];
	dij(n);
	
	for (int i=0; i<s.size(); i++)
	{
		int u=s[i].u, v=s[i].v;
		double w=s[i].w;
		
		if(dis2[u]+w+dis[v]>dis2[n]) ans=min(ans, dis2[u]+w+dis[v]); //记得加上判断!不是最短路才行,这里卡了我好久
	}
	
	printf("%.2lf", ans);
	return 0;
}
/*
3 3
0 0
1 1
0 2
1 2
1 3
2 3
*/

  

标签:1.0,int,double,短路,问题,v1,dis
From: https://www.cnblogs.com/didiao233/p/18302080

相关文章

  • 【模板】单源最短路径(弱化版)
    【模板】单源最短路径(弱化版)洛谷P3371题目背景本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步P4779。题目描述如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。输入格式第一行包含三个整数......
  • 大模型中的tempture以及top-p问题
    原文:https://blog.csdn.net/jarodyv/article/details/128994176参考:https://blog.csdn.net/engchina/article/details/138258047为了使大模型的生成和表达更加多样,GPT采用了tempture以及top-p方法。当然还有限制大模型字数的方法(max_tokens=50)。GPT的输出层后面一般跟着soft......
  • 算法学习笔记(8.6)-编辑距离问题
    目录Question:动态规划思路:第一步:思考每轮的决策,定义状态,从而得到dp表第二步:找出最优子结构,进而推导出状态转移方程第三步:确定边界条件和状态转移顺序代码实现:图例:空间优化:代码如下编辑距离,也称为Levenshtein距离,指两个字符串之间互相转化的最少修改次数,通常用于在信......
  • 算法学习笔记(8.5)-零钱兑换问题二
    目录Question:动态规划思路:代码实现:空间优化代码Question:给定n种硬币,第i种硬币的面值为coins[i-1],目标金额为amt,每种硬币可以重复选取,问凑出目标金额的硬币组合数量。动态规划思路:相比与上一题,本体的目标是求组合数量,因此子问题变为:前i种硬币能够凑出金额a的组合数......
  • ubuntu中nginx部署服务器后添加SSL证书解决SSL handshake failed问题
    文章思路:写这篇文章主要是本人在使用nginx部署好服务器后,采用浏览器打开服务器地址;在采用pyqt开发的软件中,采用QNetwork模块连接后,想下载服务器的zip压缩包时,发现QNetwork提示报了SSLhandshakefailed异常问题解决方式:添加SSL证书进行解决,目前要获取根证书有以下方式;(1)从证......
  • 1117java jsp SSM Springboot在线答疑系统学生考试问题发布教师疑难解答(源码+文档+PPT
     项目技术:Springboot+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat7.x,8.x,9.x版本均可4.硬件环境:window......
  • NSIS 之 NsDialogs 常见问题解答
    如何启用/禁用控件使用标准NSIS EnableWindow 命令。NSDialogs允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。EnableWindow 将 hwnd 作为其参数之一。通过它,您可以轻松启用/禁用控件。  !include"nsDialogs.nsh"!include"winmessages.nsh"!incl......
  • 线段树——AcWing 245. 你能回答这些问题吗
    目录线段树定义运用情况注意事项解题思路AcWing245.你能回答这些问题吗题目描述运行代码代码思路改进思路线段树定义线段树是一种用于区间查询和更新问题的数据结构。它通过递归地将一个区间分解为若干子区间,每个节点代表一个子区间的和、最小值、最大值等信息,......
  • 突破权限壁垒:彻底解决PyCharm中无法写入的权限问题
    突破权限壁垒:彻底解决PyCharm中无法写入的权限问题引言在使用PyCharm进行开发时,可能会遇到权限不足导致无法写入文件或目录的问题。这种情况通常发生在尝试保存文件到一个没有写权限的目录,或者PyCharm没有足够的权限去修改系统文件时。本文将提供一份详尽的指南,帮助你诊断......
  • lgP1253 扶苏的问题
    给定长度为n的序列A,有如下3种操作:1lrx,将区间[l,r]中的每个数都修改为x。2lrx,将区间[l,r]中的每个数都加上x。3lr,查询区间[l,r]内的最大值。分析:设置2个懒标记,先处理赋值标记,再处理增加标记。#include<bits/stdc++.h>usingllong=longlong;constllonginf=......