PAT A1018 Public Bike Management (30 分)

news/2025/2/22 22:00:48

在这里插入图片描述
这题真的是个好题目啊,基本涵盖了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;
}

http://www.niftyadmin.cn/n/827421.html

相关文章

PAT B1068 万绿丛中一点红 (20 分)

此题坑点较多&#xff0c;首先要注意所求的像素点必须是唯一出现的&#xff0c;可以用map来记录下每个输入的像素点出现的次数。然后边上一圈的像素点也是需要判断的&#xff08;题目明明说的是周围8个像素点&#xff0c;我还以为边上一圈不算&#xff09;&#xff0c;可以通过…

PAT B1069 微博转发抽奖 (20 分)

照题意模拟即可&#xff0c;可用map来存储姓名是否获奖。 #include <cstdio> #include <iostream> #include <string> #include <map> using namespace std;int main(){int m, n, s;scanf("%d %d %d", &m, &n, &s);map<stri…

PATB1070 结绳 (25 分)

看出来是考贪心算法&#xff0c;虽然不会证明&#xff0c;但是能感觉到是先把短的绳子串起来&#xff0c;然后再串长的绳子&#xff0c;这样一写果然直接AC了。 #include <cstdio> #include <algorithm> using namespace std;int main(){int n;scanf("%d&quo…

PAT A1007 Maximum Subsequence Sum (25 分)(动态规划)

DP求解最大连续子列和 #include <cstdio> #include <algorithm> using namespace std; const int maxn 100010;int n; int arr[maxn]; int dp[maxn];int main(){scanf("%d", &n);for(int i0; i<n; i){scanf("%d", &arr[i]);}int …

PAT A1045 Favorite Color Stripe (30 分)

DP求解最长不下降子序列 #include <cstdio> #include <algorithm> using namespace std; const int maxn 210; const int maxc 100010;int hashTable[maxn] {0}; int dp[maxc];int main(){int n, m;scanf("%d%d", &n, &m);for(int i1; i<…

PAT B1071 小赌怡情 (15 分)

简单模拟题 #include <cstdio>int main(){int total, k;scanf("%d %d", &total, &k);for(int i0; i<k; i){int n1, b, t, n2;scanf("%d %d %d %d", &n1, &b, &t, &n2);if(t > total){printf("Not enough tokens…

PAT B1072 开学寄语 (20 分)

乙级的题目无脑暴力就好了&#xff0c;肯定不会超时的~ 注意点&#xff1a;测试点2需要控制编号格式输出为4个的数字 #include <cstdio> #include <string> #include <iostream> using namespace std;bool hashTable[10000] {false};int main(){int m, n;s…

PAT B1073 多选题常见计分法 (20 分)

这题感觉算是比较难&#xff08;麻烦&#xff09;的乙级题目了&#xff0c;毕竟写了一个多小时。。。用了好多字符串的操作&#xff0c;可能是我太菜了吧。。。 #include <cstdio> #include <iostream> #include <string> using namespace std;struct Title…