PAT 1018 Public Bike Management (30 分)

1018 Public Bike Management (30 分)

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.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述



解析

很扎实的30分题。图应用题。
这题的要求是你从PBMT出发:沿着最短路径开始调度自行车。遇上一个station:如果这里自行车有多的:则拿走一些。如果自行车少了:就先从手头看看有没有之前在其他station收的自行车。如果没有:就要sent了。
这个行为是要一个station到另一个station:是不满足dijkstra局部最优解的。所以用dijkstra只能算最短路径。
而且不能说前面station的自行车不够:用后面的station的自行车补给。这是不对的。
在这里插入图片描述
这题有三个标尺:第一个是最短路径,可以用Dijkstra算法解决。
第二个是最少sent,第三个是最少take back。当时我一想:sent和take back不是矛盾的吗。其实我是忽略了不能说前面station的自行车不够:用后面的station的自行车补给。
所以:在所有最短路径中:看谁的sent是最少的。如果一样:就挑谁的take back最小。DFS

Code:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<utility>
using namespace std;
const int INF = 0x3fffffff;
struct Node {
	int v,len;
	Node() = default;
	Node(int _v,int _len):v(_v),len(_len){}
};
int Cmax;
vector<vector<Node>> G;
vector<int> C;
vector<vector<int>> pre;
void Dijkstra(int s, vector<int>& d) {
	vector<bool> vis(G.size(), false);
	pre.resize(G.size());
	d.resize(G.size(), INF);
	d[s] = 0;
	for (int i = 0; i < G.size(); i++) {
		int u = -1, min = INF;
		for (int j = 0; j < G.size(); j++) {
			if (vis[j] == false && min > d[j]) {
				min = d[j];
				u = j;
			}
		}
		vis[u] = true;
		for (auto x : G[u]) {
			int v = x.v;
			if (vis[v] == false) {
				if (d[v] > d[u] + x.len) {
					d[v] = d[u] + x.len;
					pre[v].clear();
					pre[v].push_back(u);
				}
				else if (d[v] == d[u] + x.len) {
					pre[v].push_back(u);
				}
			}
		}
	}
}
vector<int> temppath, path;
int minneed = INF,minremain = INF;
void DFS(int s,int v) {
	if (s == v) {
		temppath.push_back(s);
		int remain = 0,need=0;
		for (int i = temppath.size() - 2; i >= 0; i--) {
			int last = C[temppath[i]] - Cmax / 2;
			if (last > 0) {    //  有多的
				remain += last;
			}
			else {               //缺
				if (remain > abs(last))
					remain -= abs(last);
				else{
					need += abs(last) - remain;
					remain = 0;
				}
			}
		}
		if (minneed > need) {
			minneed = need;
			minremain = remain;
			path = temppath;
		}
		else if(minneed ==need ) {
			if (remain < minremain) {
				minremain = remain;
				path = temppath;
			}
		}
		temppath.pop_back();
	}
	temppath.push_back(v);
	for (auto x : pre[v])
		DFS(s, x);
	temppath.pop_back();
}
int main()
{
	int  N, Sp, M;
	scanf("%d %d %d %d", &Cmax, &N, &Sp, &M);
	G.resize(N + 1);    //0 is PBMC ,1~N is station
	C.resize(N + 1);
	for (int i = 1; i <= N; i++)
		scanf("%d", &C[i]);
	int Si, Sj, Tij;
	for (int i = 0; i < M; i++) {
		scanf("%d %d %d", &Si, &Sj, &Tij);
		G[Si].push_back(Node(Sj, Tij));
		G[Sj].push_back(Node(Si, Tij));
	}
	vector<int> d;
	Dijkstra(0,d);
	DFS(0,Sp);
	printf("%d ", minneed);
	for (int i = path.size() - 1; i >= 0; i--) {
		printf("%d", path[i]);
		if (i > 0) printf("->");
	}
	printf(" %d", minremain);

}

猜你喜欢

转载自blog.csdn.net/weixin_41256413/article/details/84889984