PAT A1018 Public Bike Management (30 分)

在这里插入图片描述
这题真的是个好题目啊,基本涵盖了Dijkstral的所有考点。
静下心来写了一个小时,发现测试点5、7过不了,自己分析了一会无果,参考了别人的博客,发现这两点是个坑,因为沿路后面的自行车无法填补前面自行车缺少的,而前面自行车多出来的可以填补后面缺少的。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 1e9;
const int MAXV = 510;

int d[MAXV];
int num[MAXV];
int G[MAXV][MAXV];
int half;
int tb = INF;
int mn = INF;
int out = 0;
int in = 0;
int c, n, p, m;
bool vis[MAXV] = {
    
    false};
vector<int> pre[MAXV], tempPath, path;

void Dijkstral(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[v] > d[u] + G[u][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 e){
    
    
	if(e == 0){
    
    
		tempPath.push_back(e);
		int need = 0;
		int back = 0;
		for(int i=0; i<tempPath.size()-1; i++){
    
    
			int index = tempPath[i];
			if(num[index] > half){
    
    
				back += (num[index]-half);
				if(need != 0){
    
    
					if(back <= need){
    
    
						need -= back;
						back = 0;
					}else{
    
    
						back -= need;
						need = 0;
					}
				}
			}else if(num[index] < half){
    
    
				need += (half-num[index]);
			}
		}
		if(need < mn){
    
    
			tb = back;
			path = tempPath;
			in = tb;
			mn = need;
			out = need;
		}else if(need == mn){
    
    
			if(back < tb){
    
    
				tb = back;
				path = tempPath;
				in = tb;
				mn = need;
				out = need;
			}
		}
		tempPath.pop_back();
	}
	tempPath.push_back(e);
	for(int i=0; i<pre[e].size(); i++){
    
    
		DFS(pre[e][i]);
	}
	tempPath.pop_back();
}

int main(){
    
    
	fill(G[0], G[0]+MAXV*MAXV, INF);
	int u, v, w;
	scanf("%d %d %d %d", &c, &n, &p, &m);
	for(int i=1; i<=n; i++){
    
    
		scanf("%d", &num[i]);
	}
	half = c/2;
	for(int i=0; i<m; i++){
    
    
		scanf("%d %d %d", &u, &v, &w);
		G[u][v] = w;
		G[v][u] = w;
	}
	Dijkstral(0);
	DFS(p);
	printf("%d ", out);
	for(int i=path.size()-1; i>=0; i--){
    
    
		printf("%d", path[i]);
		if(i != 0) printf("->");
	}
	printf(" %d", in);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45964844/article/details/113784193