7-16 城市间紧急救援 (综合最短路练习)

news2024/9/20 14:29:16
本题链接:PTA | 程序设计类实验辅助教学平台

题目:

样例:

输入
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出
2 60
0 1 3

思路:

        这道题是经典的综合最短路问题,

综合了 三种最短路方法,1.求路径条数,2.最短路多边权问题,3.求最短路的路径。

这里有个注意的点是,结点人数的的比较应该是更多更好。所以堆排序的时候,注意将结点人数总和多的排在前面。

代码详解如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#define endl '\n'
#define x first
#define y second
#define mk make_pair
#define int long long
#define NO puts("NO")
#define YES puts("YES")
#define umap unordered_map
#define INF 0x3f3f3f3f3f3f3f3f
#define All(x) (x).begin(),(x).end()
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;
using PII = pair<int,int>;

struct Edge
{
	int a;	// 相关结点
	int dis;	// 相关最短距离	
	int peo;	// 相关人数总和
	
	// 构造相关结构体
	inline Edge(int a,int dis,int peo)
	{
		this->a = a;
		this->dis = dis;
		this->peo = peo;
	}
	
	// 重载 < 比较符,建立堆排序规则
	inline bool operator<(const Edge&t)const
	{
		// 优先排序最短路问题,最短路的排前面
		if(dis != t.dis) return dis > t.dis;
		// 如果最短路相同,优先排序人数多的在前面
		return peo < t.peo;
	}
};

int n,m,k,start,last;

int havePeo[N];	// 记录经过结点的拥有总救援人数
int dist[N];	// 记录最短路距离
int peo[N];		// 记录结点城市拥有的救援人数
bool st[N];		// 标记走动的结点城市
int tree[N];	// 记录结点城市由哪上一个结点城市相连的,求路径
int treeSum[N];	// 记录路径条数
vector<int>path;	// 记录路径

int len,sum;	// sum 是总救援人数,len 是路径结点个数

// 建立链表
int h[N],e[N],ne[N],w[N],idx;
inline void Add(int a,int b,int c)
{
	e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
}

inline void Dijkstra()
{
	// 初始化最短距离和路径条数和总救援人数
	memset(dist,INF,sizeof dist);
	dist[start] = 0;
	havePeo[start] = peo[start];
	treeSum[start] = 1;
	
	// 建立堆
	priority_queue<Edge>q;
	
	// 存储起点相关结构体
	q.push(Edge(start,0,havePeo[start]));
	
	// 开始堆排序的 Dijkstra
	while(q.size())
	{
		// 获取优先走动的相关结构体
		Edge now = q.top();
		q.pop();
		
		int a = now.a;	// 获取当前走动的结点
		int dis = now.dis;	// 获取当前记录的最短路距离
		int p = now.peo;	// 获取当前记录的拥有救援总人数
		
		// 如果当前结点走动过,不必再继续更新走动
		if(st[a]) continue;
		st[a] = true;	// 标记当前走动的结点城市
		
		for(int i = h[a];i != -1;i = ne[i])
		{
			int j = e[i];	// 获取走动的结点
			// 如果 j 走动结点的最短路距离方案大于 当前解 a 结点 到 j 结点的距离
			if(dist[j] > dis + w[i])
			{
				dist[j] = dis + w[i];// 更新最短路
				treeSum[j] = treeSum[a];	// 继承路径条数
				tree[j] = a;	// 记录当前 j 结点城市是由 a 结点走动得来的
				havePeo[j] = p + peo[j];	// 记录走动到 j 结点路径拥有的总救援人数
			}else	// 如果最短距离方案 与当前 a 结点走动到 j 结点最短距离相同
			if(dist[j] == dis + w[i])
			{
				// 累计路径条数
				treeSum[j] += treeSum[a];
				
				// 如果当前 j 结点拥有的总救援人数方案 比 a 到 j 结点的总救援人数 少,那么更新路径
				if(havePeo[j] < p + peo[j])
				{
					havePeo[j] = p + peo[j];	// 更新走动到 j 结点路径拥有的总救援人数
					tree[j] = a;	// 更新结点城市路径
				}
			}
			// 存储走动的 j 结点,进行下一次的走动比较
			q.push(Edge(j,dist[j],havePeo[j]));
		}
	}
}

// 获取最短路的路径
void getPath(int now)
{
	// 递归到了起点,开始回溯取路径
	if(now == start)
	{
		// 存储路径
		path.emplace_back(now);
		++len;	// 记录路径点个数
		sum += peo[now];	// 累加救援人数
		return ;
	}
	
	// 递归求路径
	getPath(tree[now]);
	
	// 存储路径
	path.emplace_back(now);
	++len;	// 记录路径点个数
	sum += peo[now];	// 累加救援人数
}

inline void solve()
{
	// 初始化链表
	memset(h,-1,sizeof h);
	
	cin >> n >> k >> start >> last;
	
	for(int i = 0;i < n;++i)
	{
		cin >> peo[i];
	}
	
	while(k--)
	{
		int a,b,c;
		cin >> a >> b >> c;
		
		// 相连两个城市
		Add(a,b,c);
		Add(b,a,c);
	}
	
	// Dijkstra 求值
	Dijkstra();
	
	// 由终点回溯递归获取路径
	getPath(last);
	
	// 输出 路径条数,和 救援人员总人数
	cout << treeSum[last] << ' ' << sum << endl;
	
	// 输出救援路径
	for(int i = 0;i < len;++i)
	{
		if(i) cout << ' ';
		cout << path[i];
	}
}

signed main()
{
//	freopen("a.txt", "r", stdin);
	___G;
	int _t = 1;
//	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

最后提交:

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

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

相关文章

Flutter AI五子棋

前言 在上一篇文章中&#xff0c;讲解了如何实现双人在本地对战的五子棋&#xff0c;但是只有一个人的时候就不太好玩&#xff0c;同时博主也没有把五子棋相关的文章写过瘾。那么这篇文章&#xff0c;我们来实现一个功能更加丰富的五子棋吧&#xff01;在设计五子棋的算法方面&…

MongoDB数据库网站网页实例-编程语言Python+Django

程序示例精选 PythonDjangoMongoDB数据库网站网页实例 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonDjangoMongoDB数据库网站网页实例》编写代码&#xff0c;代码整洁&#xff0c;…

【软件测试】软件测试的基础概念

一、一个优秀的测试人员需要具备的素质 技能方面&#xff1a; 优秀的测试用例设计能力&#xff1a;测试用例设计能力是指&#xff0c;无论对于什么类型的测试&#xff0c;都能够设计出高效的发现缺陷&#xff0c;保证产品质量的优秀测试用例。这就需要我们掌握设计测试用例的方…

【Docker】初识 Docker,Docker 基本命令的使用,Dockerfile 自定义镜像的创建

文章目录 前言&#xff1a;项目部署的挑战一、初识 Docker1.1 什么是 Docker1.2 Docker 与 虚拟机的区别1.3 镜像和容器以及镜像托管平台1.4 Docker的架构解析1.5 Docker 在 CentOS 中的安装 二、Docker 的基本操作2.1 操作 Docker 镜像命令2.1.1 镜像操作相关命令2.1.2 示例一…

C/C++字符函数和字符串函数模拟实现与详解————长度不受限制的字符串函数

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2strlen函数 3.strcpy函数…

通过BeanFactotyPostProcessor动态修改@FeignClient的path

最近项目有个需求&#xff0c;要在启动后&#xff0c;动态修改FeignClient的请求路径&#xff0c;网上找到的基本都是在FeignClient里使用${…}&#xff0c;通过配置文件来定义Feign的接口路径&#xff0c;这并不能满足我们的需求 由于某些特殊原因&#xff0c;我们的每个接口…

【算法|动态规划No.9】leetcodeLCR 091. 粉刷房子

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

2023/10/4 QT实现TCP服务器客户端搭建

服务器端&#xff1a; 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { cla…

便携式脑卒中检测仪是不是离现实不远了?

摘要&#xff1a;本文介绍一个轻量级人工智能的应用--基于tinyML的便携式低成本脑部微波成像系统。参考资料为DOI&#xff1a; 10.1109/ISCAS46773.2023.10181746 医疗资源从来都是稀缺资源。 我们都经历过在医院CT和核磁共振室外排队的情况。即使您万分紧急&#xff0c;也只能…

实验3.2 分期付款计算器

目录 实验目的‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬ 实验内容‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬…

【算法与数据结构】归并排序的代码实现(详细图解)以及master公式的讲解

目录 1、归并排序 1.1、算法描述 1.2、图解说明 2、代码实现 3、master公式 3.1、公式以及结论 3.2、适用于某些特殊的递归 3.3、计算归并排序的时间复杂度 1、归并排序 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用递归或者说是分治法&#xff08;Di…

基于SpringBoot的桂林旅游景点导游平台

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 景点类型管理 景点信息管理 线路推荐管理 用户注册 线路推荐 论坛交流 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实…

Unity基于种子与地块概率的开放世界2D地图生成

public class BuildingGen : MonoBehaviour {public int[] Building;//存储要生成的地块代码public int[] Probability;//存储概率public double seed;public int width 100;public int height 100;public float noiseScale 0.1f; //噪声缩放倍数private int[,] frequencyM…

基于Java的驾校收支管理可视化平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

揭秘亚马逊、ebay自养号测评底层环境防关联技术

今天珑哥讲的是纯人工的自养号方式&#xff0c;已经在做过的人应该都懂&#xff0c;实现自养号所使用的IP和浏览器都有哪些 &#xff1f;都会有哪些问题。 一&#xff1a;市面上的IP有哪些&#xff1f;会遇到的问题&#xff1f; 922、luminati、googelfi、TM流量卡、Rola&…

基于Matlab求解高教社杯数学建模竞赛(cumcm2010A题)-储油罐的变位识别与罐容表标定(附上源码+数据+题目)

文章目录 题目解题源码数据下载 题目 通常加油站都有若干个储存燃油的地下储油罐&#xff0c;并且一般都有与之配套的“油位计量管理系统”&#xff0c;采用流量计和油位计来测量进/出油量与罐内油位高度等数据&#xff0c;通过预先标定的罐容表&#xff08;即罐内油位高度与储…

CentOS 7 停止维护后如何平替你的生产系统?

Author&#xff1a;rab 目录 前言一、Debian 家族1.1 Debian1.2 Ubuntu 二、RHEL 家族2.1 Red Hat Enterprise Linux2.2 Fedora2.3 CentOS2.4 Rocky Linux2.5 AlmaLinux 三、如何选择&#xff1f;思考&#xff1f; 前言 CentOS 8 系统 2021 年 12 月 31 日已停止维护服务&…

NPDP产品经理知识(产品创新种的市场调研)

1. 复习产品设计与开发工具 创意生成&#xff1a; scamper也叫蹦蹦法 心智图就是思维导图&#xff1a;mindmaping 原型法--故事板&#xff1a;创意生成的时候做的 人种学--民族志 六顶思考帽&#xff1a;白色红色黑色蓝色。。。 概念设计&#xff1a; AOMI&#xff1a;卡…

BIRCH算法全解析:从原理到实战

目录 一、引言什么是BIRCH算法BIRCH算法的应用场景文章目标和结构概述 二、BIRCH算法基础CF&#xff08;Clustering Feature&#xff09;树的概念数据点簇簇的合并和分裂 BIRCH的时间复杂度和空间复杂度BIRCH vs K-means和其他聚类算法 三、BIRCH算法的技术细节CF树的构建节点和…

潮流来袭!中国首届虚拟艺术巡展NFS将在广州YCC!天宜盛大开启!

中国首届虚拟艺术巡展 NFT Showcase (NFS) 即将来袭&#xff0c;本活动由 Web3 营销公司 Beep Crypto 精心策划&#xff0c;将于 10 月 5 日至 10 月 17 日在广州潮流策展空间 YCC!天宜举行。 活动的主题围绕虚拟时尚展开&#xff0c;汇聚了一系列令人激动的展品&#xff0c;涵…