PAT甲级 1018 Public Bike Management (30 分) 题解

PAT甲级 1018 Public Bike Management (30 分) 题解_第1张图片PAT甲级 1018 Public Bike Management (30 分) 题解_第2张图片PAT甲级 1018 Public Bike Management (30 分) 题解_第3张图片
\quad 这个题目的是要我们能记录所有的最短路径,在这些路径中选择符合题目的那一种输出。我用vector pre[maxn]数组记录符合最短路时节点的前驱节点,用Dijistra获得这个数组。最后用DFS对pre数组进行深搜,找出所有的最短路径来计算需要从中心拿走的自行车数量和需要带回中心的数量,比较输出在从中心带出自行车数量最少的前提下带回中心数量最少的那一种解答,记录此路径,输出即可。关于如何获得一个点到另一个点所有的最短路径,欢迎点击博客求图中两点间的所有的最短路径,我在博客里面进行了详细的阐述。

#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 501;
vector<pair<int, int> > E[maxn];
vector<int> pre[maxn], temp, path;
int vis[maxn], dis[maxn];
int num[maxn];  // 记录每个点自行车数目
void dijstra(int s)
{
	fill(dis, dis+maxn, 0x3f3f3f3f);
	dis[s] = 0;
	priority_queue<pair<int, int> > q;
	q.push(make_pair(0, s));
	while(!q.empty())
	{
		int u = q.top().second;
		q.pop();
		if(vis[u]==1) continue;
		vis[u] = 1;
		for (int i = 0; i < E[u].size(); ++i)
		{
			int v = E[u][i].first, w = E[u][i].second;
			if(dis[v]>dis[u]+w)
			{
				dis[v] = dis[u]+w;
				pre[v].clear();
				pre[v].push_back(u);
				if(vis[v]==0) q.push(make_pair(-dis[v], v));
			}
			else if(dis[v]==dis[u]+w)
			{
				pre[v].push_back(u);
				if(vis[v]==0) q.push(make_pair(-dis[v], v));
			}
		}
	}
}
int minNeed=0x3f3f3f3f, minBack=0x3f3f3f3f;
void dfs(int v)
{
	if(v==0) 
	{
		temp.push_back(v);
		int need = 0, back = 0;
		for (int i = temp.size()-1; i >= 0; i--)
		{
			int id = temp[i];
			if(num[id] > 0) back += num[id];
			else{
				if(back > (0-num[id])) back += num[id];
				else{
					need += ((0-num[id])-back);
					back = 0;
				}
			}
		}
		if(need<minNeed) minNeed=need, minBack=back, path=temp;
		else if(need==minNeed && back<minBack) minBack=back, path=temp;
		temp.pop_back();
		return;
	}
	temp.push_back(v);
	for (int i = 0; i < pre[v].size(); ++i)
	{
		dfs(pre[v][i]);
	}
	temp.pop_back();
}
int main(int argc, char const *argv[])
{
	int C, N, s, M;
	cin >> C >> N >> s >> M;
	for(int i = 1; i <= N; i++) cin >> num[i], num[i]-=C/2;
	while(M--)
	{
		int u, v, w;
		cin >> u >> v >> w;
		E[u].push_back(make_pair(v, w));
		E[v].push_back(make_pair(u, w));
	}
	dijstra(0);
	dfs(s);
	cout << minNeed << " 0";
	for (int i = path.size()-2; i >= 0; i--)
	{
		cout << "->"<< path[i];
	}
	cout << " " << minBack;
	return 0;
}

你可能感兴趣的:(PAT甲级)