PAT 1018 Public Bike Management

news2025/1/19 20:29:18

个人学习记录,代码难免不尽人意。

There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.

The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.

When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.
在这里插入图片描述
在这里插入图片描述
Sample Input:
10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1
Sample Output:
3 0->2->3 0

一开始我只用了dijkstra,结果只得到了23分。

#include <cstdio>
#include<set>
#include<string>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int cmax,n,sp,m;
const int maxn=510;
const int INF=1000000000;
int C[maxn];
int G[maxn][maxn];
int sent[maxn];
int take[maxn];
int d[maxn];
int pre[maxn];
bool visit[maxn]; 
void dijkstra(int st){
	fill(visit,visit+n+1,false);
	fill(d,d+n+1,INF);
	sent[st]=0;
	take[st]=0;
	d[st]=0;
	for(int i=0;i<=n;i++){
		int m=-1,min=INF;
		for(int j=0;j<=n;j++){
			if(!visit[j]&&d[j]<min){
				min=d[j];
				m=j;
			}
		}
		if(m==-1) return;
		visit[m]=true;
		for(int j=0;j<=n;j++){
			if(!visit[j]&&G[m][j]!=INF&&d[j]>d[m]+G[m][j]){
				d[j]=d[m]+G[m][j];
//				cout << "m=" << m <<"C[j]=" << C[j] <<endl; 
				if(cmax/2-C[j]==0){
					sent[j]=sent[m];
					take[j]=sent[m];
				}
				else if(cmax/2-C[j]<0){//需要拿走 
					sent[j]=sent[m];
					
					take[j]=take[m]+abs(cmax/2-C[j]);
				}
				else{//需要带来 
					sent[j]=max(0,(cmax/2-C[j])-take[m]);
					take[j]=max(0,take[m]-(cmax/2-C[j]));
				}
				pre[j]=m;
			}
			else if(!visit[j]&&G[m][j]!=INF&&d[j]==d[m]+G[m][j]){
				if(cmax/2-C[j]==0){
					if(sent[j]>sent[m]){
					sent[j]=sent[m];
					take[j]=take[m];
					pre[j]=m;
					}
				}
				else if(cmax/2-C[j]<0){//需要拿走 
				    if(sent[j]>sent[m]){
				    	sent[j]=sent[m];
					take[j]=take[m]+abs(cmax/2-C[j]);
					pre[j]=m;
					}
					
				}
				else{//需要带来 
				    if(sent[j]>max(0,(cmax/2-C[j])-take[m])){
				    	sent[j]=max(0,(cmax/2-C[j])-take[m]);
					take[j]=max(0,take[m]-(cmax/2-C[j]));
					pre[j]=m;
					}
					
				}
			}
		}
	}
}
void dfs(int num){
	if(pre[num]==num){
		printf("%d",num);
		return;
	}
	dfs(pre[num]);
	printf("->%d",num);
}
int main(){
  scanf("%d%d%d%d",&cmax,&n,&sp,&m);
  C[0]=0;pre[0]=0;
  for(int i=1;i<=n;i++){
  	scanf("%d",&C[i]);
  }
  for(int i=0;i<=n;i++){
  	for(int j=0;j<=n;j++){
  		G[i][j]=INF;
	  }
  }
  for(int i=1;i<=m;i++){
  	int a,b,dis;
  	scanf("%d%d%d",&a,&b,&dis);
  	G[a][b]=dis;
  	G[b][a]=dis;
  }
  dijkstra(0);
//  for(int i=0;i<n+1;i++){
//  	printf("%d ",take[i]);
//  }
//  for(int i=0;i<n+1;i++){
//  	printf("%d ",sent[i]);
//  }
  printf("%d ",sent[sp]);
  dfs(sp);
  printf(" %d\n",take[sp]);
  
}

后来我看了答案才发现不能只使用dijkstra方法来做,因为路径不满足最优子结构,必须采用dijkstra和dfs的方法来做。
正确代码如下:

//1018 Public Bike Management(30 分)
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXV = 510;
const int INF = 1000000000;
int n, m, Cmax, Sp, numPath = 0, G[MAXV][MAXV], weight[MAXV];
int d[MAXV], minNeed = INF, minRemain = INF;//minNeed记录最少携带的数目,minRemain记录最少带回的数目
bool vis[MAXV] = { false };
vector<int>pre[MAXV];
vector<int>tempPath, path;
void Dijkstra(int s) {
	fill(d, d + MAXV, INF);
	d[s] = 0;
	for (int i = 0; i <= n; i++) {
		int u = -1, MIN = INF;
		for (int j = 0; j <= n; j++) {
			if (vis[j] == false && d[j] < MIN) {
				u = j;
				MIN = d[j];
			}
		}
		if (u == -1)return;
		vis[u] = true;
		for (int v = 0; v <= n; v++) {
			if (vis[v] == false && G[u][v] != INF) {
				if (d[u] + G[u][v] < d[v]) {
					d[v] = d[u] + G[u][v];
					pre[v].clear();
					pre[v].push_back(u);
				}
				else if (d[v] == d[u] + G[u][v])pre[v].push_back(u);
			}
		}
	}
}
void DFS(int v) {
	if (v == 0) {
		tempPath.push_back(v);
		//计算最短路径标尺
		int need = 0, remain = 0;
		for (int i = tempPath.size() - 1; i >= 0; i--) {
			int id = tempPath[i];
			if (weight[id] > 0) {
				//如果当前节点点权为正,说明需要收走自行车,收走数量为点权值
				remain += weight[id];
			}
			else {
				//如果点权为负,则从前面收走的remain中向该节点投放自行车
				if (remain > abs(weight[id]))remain -= abs(weight[id]);
				else {
					//如果不够投放,需要从PBMC携带
					need += abs(weight[id]) - remain;
					remain = 0;//当前持有的自行车全部用来补给
				}
			}
		}
		if (need < minNeed) {//最短路径相同,选择需要从PBMC带的最少的情况
			minNeed = need;
			minRemain = remain;
			path = tempPath;
		}
		else if (need == minNeed && remain < minRemain) {//need还相同,选择remain少的情况
			minRemain = remain;
			path = tempPath;
		}
		tempPath.pop_back();
		return;
	}
	tempPath.push_back(v);
	for (int i = 0; i < pre[v].size(); i++) {
		DFS(pre[v][i]);
	}
	tempPath.pop_back();
}
int main() {
	(void)scanf("%d %d %d %d", &Cmax, &n, &Sp, &m);
	int u, v;
	fill(G[0], G[0] + MAXV * MAXV, INF);
	for (int i = 1; i <= n; i++) {
		(void)scanf("%d", &weight[i]);
		weight[i] -= Cmax / 2;//点权减去容量的一半,计算距离prefect还差多少
	}
	for (int i = 0; i < m; i++) {
		(void)scanf("%d %d", &u, &v);
		(void)scanf("%d", &G[u][v]);
		G[v][u] = G[u][v];
	}
	Dijkstra(0);
	DFS(Sp);
	printf("%d ", minNeed);
	for (int i = path.size() - 1; i >= 0; i--) {
		//路径的顺序是倒序存放的
		printf("%d", path[i]);
		if (i > 0)printf("->");
	}
	printf(" %d", minRemain);
	return 0;
}

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

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

相关文章

微服务基础概念【内含图解】

目录 拓展补充&#xff1a; 单体架构 分布式架构 面向服务的体系结构 云原生 微服务架构 什么是微服务&#xff1f; 微服务定义 拓展补充&#xff1a; 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;最终打成一个包部署 优点&#x…

Hlang--用Python写个解释器

文章目录 前言流程数学解释器结果封装数的操作运行时异常运行解释实现总结前言 没错今天提前来做这个东西,昨天晚上干这个玩意差不多干了两个多小时才搞定,导致凌晨2点才睡觉,最要命的是,写着写着突然想到有一道线代理解错了,一个晚上,做梦全是这两个东西。尤其是晚上效…

一篇学会软硬链接|快捷方式|操作系统|centos7

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总https://blog.csdn.net/yu_cblog/categ…

安装和配置 Ansible

安装和配置 Ansible 按照下方所述&#xff0c;在控制节点 control.area12.example.com 上安装和配置 Ansible&#xff1a; 安装所需的软件包 创建名为 /home/curtis/ansible/inventory 的静态清单文件&#xff0c;以满足以下要求&#xff1a; node1 是 dev 主机组的成员 node2 …

【C语言】字符串和内存函数的介绍 -- 详解

重点介绍处理字符和字符串的库函数的使用和注意事项。 C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。 一、求字符串长度⚪strlen …

LC-对称二叉树

LC-对称二叉树 链接:https://leetcode.cn/problems/symmetric-tree/description/ 描述&#xff1a;给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 例1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 例2&#xff1a; 输入&…

【C++】—— 详解AVL树

目录 序言 &#xff08;一&#xff09;AVL树的概念 1、AVL树的由来 2、AVL树的特点 3、平衡因子 &#xff08;二&#xff09;AVL树的插入 1、插入操作的思想理解 2、AVL树的旋转 1️⃣ LL平衡旋转&#xff08;右单旋转&#xff09; 2️⃣ RR平衡旋转&#xff08;左单…

基于Canal实现MySQL 8.0 数据库数据同步

前言 服务器说明 主机名称操作系统说明192.168.11.82Ubuntu 22.04主库所在服务器192.168.11.28Oracle Linux Server 8.7从库所在服务器 版本说明 <span style"color:#000000"><span style"background-color:#ffffff"><code class"la…

carla中lka实现(二)

前言&#xff1a; 首先计算之前检测出来的车道线的中线与输入图像的中线进行计算距离&#xff0c;&#xff0c;并设置不同的阈值对于不同的方向进行相关的调整。 一、车辆中心线 一般而言将摄像头架设在车辆的正中心轴上&#xff0c;所获得的图像的中间线极为车辆的中心。 …

激光雷达 01 线数

一、线数 对于 360 旋转式和一维转镜式架构的激光雷达来说&#xff0c;有几组激光收发模块&#xff0c;垂直方向上就有几条线&#xff0c;被称为线数。这种情况下&#xff0c;线数就等同于激光雷达内部激光器的数量[参考]。 通俗来讲&#xff0c;线数越高&#xff0c;激光器的…

Adobe Acrobat 无法使用 PS 编辑图片 的解决方法

问题描述 使用较新版本的Adobe Acrobat时&#xff0c;有时会遇到问题。 比如对pdf中的图片使用 PS 进行编辑&#xff0c;会弹出以下窗口&#xff0c;导致打不开 PS &#xff0c;无法对图片进行编辑。 Adobe 无法启动您指定的图像编辑应用程序。请在"首选项"的"…

【STM32CubeMX】低功耗模式

前言 本文讲解STM32F10X的低功耗模式&#xff0c;部分资料参考自STM32手册。STM32F10X提供了三种低功耗模式&#xff1a;睡眠模式&#xff08;Sleep mode&#xff09;、停机模式&#xff08;Stop mode&#xff09;和待机模式&#xff08;Standby mode&#xff09;。这些低功耗模…

双环传动CIO吴学信:数字化转型为企业高效运转和业绩腾飞提供重要支撑

引言 浙江双环传动机械股份有限公司&#xff08;股票代码&#xff1a;002472&#xff09;创建40年来专注于机械传动核心部件——齿轮及其组件的研发、制造与销售&#xff0c;已成为全球最大的专业齿轮产品制造商和服务商之一。 2019年以来&#xff0c;双环传动与纷享销客CRM建…

【0Ω电阻在PCB板中的5大常见作用】

文章目录 前言1、充当跳线2、进行调试时的前后级隔离3、让调试更灵活4、方便测试电流5、用于单点接地 前言 在PCB板中&#xff0c;时常见到一些阻值为0Ω的电阻。我们都知道&#xff0c;在电路中&#xff0c;电阻的作用是阻碍电流&#xff0c;而0Ω电阻显然失去了这个作用。那…

LC-将有序数组转换为二叉搜索树

LC-将有序数组转换为二叉搜索树 链接&#xff1a;https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/description/ 描述&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索…

new String()到底创建了几个对象

题目&#xff1a; new String&#xff08;"abc"&#xff09;会创建几个对象&#xff1f; 看字节码&#xff0c;就知道是两个。

经验分享丨HR告诉你:同样是找工作,这些简历绝对会被直接刷掉!

上次的文章分享了自己软件测试面试时的一些经历&#xff0c;今天我想分享一下自己当时写简历以及投简历方面的经历&#xff0c;本文内容纯粹是个人简单分享&#xff0c;如果有写得不好的地方还请读者包涵与指正。 我是去年的九月初开始投递简历的&#xff0c;貌似各行各业的人都…

[JavaWeb]【七】web后端开发-MYSQL

前言&#xff1a;MySQL是一种流行的关系型数据库管理系统,它的作用是存储和管理数据。在Web开发中,MySQL是必备的数据库技能之一,因为它可以帮助Web开发人员处理大量的数据,并且提供了强大的数据查询和管理功能。 一 数据库介绍 1.1 什么是数据库 1.2 数据库产品 二 MySQL概述…

电煎锅出口欧洲CE认证标准

电煎锅是家庭烹饪中比较常见的电器&#xff0c;一般家庭在日常生活中都会使用&#xff0c;所以电煎锅具有广大的市场&#xff0c;尤其在欧洲市场更是日常烹饪离不开的家庭电器。欧洲是我国出口比例占比较大的地区&#xff0c;每年出口到欧洲的家庭电器占很大一部分。而根据欧盟…

3 Python的数据类型

概述 在上一节&#xff0c;我们介绍了Python的基础语法&#xff0c;包括&#xff1a;编码格式、标识符、关键字、注释、多行、空行、缩进、引号、输入输出、import、运算符、条件控制、循环等内容。Python是一种动态类型的编程语言&#xff0c;这意味着当你创建一个变量时&…