PAT甲级刷题之路——A1087 All Roads Lead to Rome

PAT A1087 All Roads Lead to Rome(30分)


看标题应该是个图论题吧。
(最短路径问题)

原题如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目大意

找出在花费最少的路径的同时获得最大幸福度。
输入:
第一行包含城市数量N、两个城市间的路线数量K和起始城市的名字。
接下来N-1行代表除了起始城市路过该城市名字和获得的幸福指数。
接下来K行是两个城市的名字和两个城市的路线花费。
用三个字符代表城市名字,罗马用”ROM“代表。
输出:
先考虑最短路径,若最短路径不唯一,则使得幸福指数最大;若仍不唯一,则使平均幸福指数最大。
输出最小花费的路径数、花费、幸福数、平均幸福数(只取整数部分)

自己的想法

就是多指标的dijkstra指标:路径花费、幸福指数、平均幸福指数(可以用路经城市数和幸福指数来衡量)
城市名字可以用map来对应。

答案反馈

在这里插入图片描述
我按照我的思路调通了样例就AC了。
在调样例的图中遇到了一个错误点就是我一开始把它当作了有向图,其实是无向图。

AC代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<set>
#include<queue>
#include<map>
#include<stack>
using namespace std;
map<string, int> mp;
map<int, string> mp1;
int happiness[210];
int rode[210][210];
int minrode[210];
const int inf = 1000000;
int n, k;
bool judge[210] = { false };
int maxrode[210] = { 0 };
int w[210] = { 0 };
vector<int> pre[210];
stack<int>ans_rode;
void dijskra(int start) {
	minrode[start] = 0;
	maxrode[start] = 1;
	for (int i = 0; i < n; i++) {
		int u = -1, min = inf;
		for (int j = 0; j < n; j++) {
			if (minrode[j] < min&&judge[j]==false) {
				u = j; min = minrode[j];
			}
		}
		if (u == -1)return;
		judge[u] = true;
		for (int v = 0; v < n; v++) {
			if (judge[v] == false&&rode[u][v]!=inf) {
				if (minrode[u] + rode[u][v] < minrode[v]) {
					minrode[v] = minrode[u] + rode[u][v];
					maxrode[v] = maxrode[u];
					w[v] = w[u] + happiness[v];
					pre[v].clear();
					pre[v].push_back(u);
				}
				else if (minrode[u] + rode[u][v] == minrode[v]) {
					maxrode[v] += maxrode[u];
					if (w[u] + happiness[v] > w[v]) { w[v] = w[u] + happiness[v];
					pre[v].clear(); pre[v].push_back(u);
					}
					else {
						pre[v].push_back(u);
					}
				}
			}
		}

	}
}
int num(int start,int end,int sum) {
	if (end == start)return sum;
	ans_rode.push(pre[end][0]);
	num(start, pre[end][0], sum + 1);
}
int main() {
#ifdef test
	freopen("input.txt", "r", stdin);
#endif
	//初始化
	fill(rode[0], rode[0] + 210 * 210, inf);
	fill(minrode, minrode + 210, inf);
	string start;
	cin >> n >> k >> start;
	int index = 0;
	mp[start] = index++;
	mp1[index - 1] = start;
	for (int i = 0; i < n - 1; i++) {
		string str;
		int data;
		cin >> str >> data;
		mp[str] = index++;
		mp1[index - 1] = str;
		happiness[mp[str]] = data;
	}
	for (int i = 0; i < k; i++) {
		string str1, str2;
		cin >> str1 >> str2;
#ifdef test
		cout << mp[str1] << ' ' << mp[str2] << ' ';
#endif
		cin >> rode[mp[str1]][mp[str2]];
#ifdef test
		cout << rode[mp[str1]][mp[str2]] << endl;
#endif
		rode[mp[str2]][mp[str1]] = rode[mp[str1]][mp[str2]];
	}
#ifdef test
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cout << rode[i][j] << ' ';
		}
		cout << endl;
	}
#endif
	dijskra(mp[start]);
	ans_rode.push(mp["ROM"]);
	int ans=num(mp[start],mp["ROM"],0);
	ans = ceil(w[mp["ROM"]] / ans);
	cout << maxrode[mp["ROM"]] << ' ' << minrode[mp["ROM"]] << ' ' << w[mp["ROM"]] << ' '<<ans<<endl;
	for (int i = 0; !ans_rode.empty(); i++) {
		if (i != 0) {
			cout << "->";
		}
		cout << mp1[ans_rode.top()];
		ans_rode.pop();
	}
	cout << endl;
	return 0;
}

结语

已经九月中旬了,感觉旁边很多人都已经保研成功了,不乏有很多清北的,心里有点慌,今天老师约视频面试,加油!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值