PAT真题练习(甲级)1018 Public Bike Management (30 分)

PAT真题练习(甲级)1018 Public Bike Management (30 分)

原题网址:https://pintia.cn/problem-sets/994805342720868352/problems/994805489282433024

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.

在这里插入图片描述

在这里插入图片描述

Input Specification:

在这里插入图片描述

Output Specification:

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

思路 :

整体思路:

  1. 用Dijsk算法,算出所有到Sp的最短路径
  2. 遍历所有最短路径,比较他们所需要带出和带回的bike数量
  3. 得到最终结果

AC代码

#include <stdio.h>
#include <iostream>
#include <stack>
#include <vector>
#include <string>
#include<math.h>
#include <algorithm>
using namespace std;
static int MAX = 99999;
int roads[501][501];
vector<bool> is_visited;
int C, N, S, M;
vector<int> cnumber;//各节点当前bike数量
vector<vector<int>> parent; // 最短路径的父节点
vector<int> dis; // 从PBMC到各点的距离
int min_tnumber = MAX; // 从PBMC带去的bike数量
int min_bnumber = MAX; // 最终带回的bike数量
string path;//最终的path 
deque<int> cpath;//路径

void Find() {
	string npath = "0";
	int bnumber = 0; // 当前手中的多余bike数量 
    int tnumber = 0;//需要从PBMC带的bike数量
	for (auto i = 1;i < cpath.size();i++) {
		npath += "->";
		npath += to_string(cpath[i]);
        // 若当前station的数量大于C/ 2
		if (cnumber[cpath[i]] > C / 2) bnumber += cnumber[cpath[i]] - C / 2;
		else {
            // 若当前station的数量小于C/ 2 且手头已有的bike数量足够弥补
			if (bnumber >= C / 2 - cnumber[cpath[i]]) bnumber -= C / 2 - cnumber[cpath[i]];
            // 若已有的bike数量不够弥补,则其余需要从PBMC带出
			else {
				tnumber += C / 2 - cnumber[cpath[i]] - bnumber;
				bnumber = 0;
			}
		}
	}
    // 比较带出的bike数量
	if (tnumber < min_tnumber) {
		path = npath;
		min_tnumber = tnumber;
		min_bnumber = bnumber;
	}
    // 若带出的bike数量相等,则比较带回的bike数量
	else if (tnumber == min_tnumber && bnumber < min_bnumber ) {
		path = npath;
		min_bnumber = bnumber;
	}
}

// 计算最短路径
void Dijsk() {
	while (true) {
		int min_dis = MAX;
		int next = -1;
		for (auto i = 0; i <= N;i++) {
			if (!is_visited[i] && dis[i] < min_dis) {
				min_dis = dis[i];
				next = i;
			}
		}
		if (next == -1) break;
		is_visited[next] = true;
		for (auto i = 0;i <= N;i++) {
			if (!is_visited[i] && roads[next][i] != MAX) {
				if (dis[next] + roads[next][i] < dis[i]) {
					dis[i] = dis[next] + roads[next][i];
					parent[i].clear();
					parent[i].push_back(next);
				}
				else if (dis[next] + roads[next][i] == dis[i])
					parent[i].push_back(next);
			}
		}
	}
	
}
// 遍历所有最短路径
void DFS(int root) {
	cpath.push_front(root);
	if (root == 0)  Find();
	for (auto item : parent[root]) {
		DFS(item);
	}
	cpath.pop_front();
}
int main() {
	cin >> C >> N >> S >> M;
	cnumber.resize(N + 1);
	parent.resize(N + 1);
	dis.resize(N + 1,MAX);
    is_visited.resize(N + 1,false);
    fill(roads[0],roads[0] + 501 * 501,MAX);
	for (auto i = 1; i <= N;i++) {
		cin >> cnumber[i];
	}
	int S1, S2, T;
	for (auto i = 0; i < M; i++) {
		cin >> S1 >> S2 >> T;
		roads[S1][S2] = roads[S2][S1] = T;
	}
	dis[0] = 0;
	Dijsk();
	DFS(S);
	cout << min_tnumber << " " << path << " "<<min_bnumber;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值