PAT-A1087-All Roads Lead to Rome-附题解

本文介绍了一种算法,用于解决寻找连接多个城市中最快乐且成本最低的路径的问题。该算法结合了Dijkstra算法和DFS搜索,以确定从任意城市到罗马的路径,同时考虑路径的总成本、最大快乐值及平均快乐值。

PS:刷题时的代码,基本没有改过,测试点都通过了。放上来总结一下思路与方法。

1.题目阐述

给定城市之间的路径以及各个城市的快乐程度,先找出到达rom的最短路径,若有多条求出路经城市的快乐数和,若仍有相同,则输出平均城市快乐数。

2.题目思路

  1. 利用map作string与int的映射
  2. 这里有多个指标,因此利用《算法笔记》的dijskal(路线记录)+DFS(路数+花费+快乐数+平均快乐)模板分开得到数据

3.题解代码

我的代码如下:

/*

要求:

1. If such a route is not unique, the one with the maximum happiness will be recommanded.
If such a route is still not unique, then we output the one with the maximum average happiness it is guaranteed by the judge that such a solution exists and is unique.

least cost->maxmun happyness->average happyness

2. the number of different routes with the least cost, the cost, the happiness, and the average happiness
(take the integer part only) of the recommanded route.
3. print the route in the format City1->City2->...->ROM

思路:
1.dijskal(路线记录)+DFS(路数+花费+快乐数+平均快乐)
*/

#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<string>
#include<algorithm>


using namespace std;

vector<int> pre[201];
int d[201];
bool vis[201] = { false };


struct node{
	int v;
	int w;
};
vector<node> G[201];
int happy[201];
int N, K;
string start;
map<string, int> stringToInt;
map<int, string> intToString;
const int INF = 100000001;



node newNode(int to, int dis){
	node Node;
	Node.v = to;
	Node.w = dis;
	return Node;
}

int getId(string s){
	if (stringToInt.find(s) != stringToInt.end()){
		return stringToInt[s];
	}
	else{
		int id = stringToInt.size();
		stringToInt[s] = id;
		intToString[id] = s;
		return id;
	}
}

void dijsktra(int s){
	fill(d, d + N, INF);
	d[s] = 0;

	for (int i = 0; i < N; i++){

		int MIN = INF, u = -1;
		for (int j = 0; j < N; j++){
			if (vis[j] == false && MIN>d[j]){
				MIN = d[j];
				u = j;
			}
		}

		if (u == -1) return;
		vis[u] = true;

		for (int j = 0; j < G[u].size(); j++){
			node temp = G[u][j];
			if (vis[temp.v] == false){
				if (d[u] + temp.w < d[temp.v]){
					d[temp.v] = d[u] + temp.w;
					pre[temp.v].clear();
					pre[temp.v].push_back(u);
				}
				else if (d[u] + temp.w == d[temp.v]){
					pre[temp.v].push_back(u);
				}
			}
		}
	}
}


int temp_value, temp_avg_value;
int num_path = 0;
int optValue = -INF, optAvgValue = -INF;
vector<int> path, temppath;


int cal_value(vector<int> v){
	int Sum = 0;
	for (int i = 0; i < v.size(); i++){
		Sum += happy[v[i]];
	}
	return Sum;
}

//记录路线长度|最优路线|快乐数
void DFS(int v){



	if (v == 0){
		//起点不用加入!
		num_path++;
		temp_value = cal_value(temppath);
		temp_avg_value = temp_value / temppath.size();
		if (temp_value == optValue && temp_avg_value>optAvgValue){
			path = temppath;
			optAvgValue = temp_avg_value;
		}else if(temp_value > optValue ){
            optValue=temp_value;
            path = temppath;
			optAvgValue = temp_avg_value;
        }
        return ;


	}


	temppath.push_back(v);
	for (int i = 0; i < pre[v].size(); i++){
		DFS(pre[v][i]);
	}
	temppath.pop_back();
}
int main(){


	cin >> N >> K >> start;
	getId(start);
	int id, happyness;
	string temp;
	for (int i = 0; i < N - 1; i++){
		cin >> temp >> happyness;
		id = getId(temp);
		happy[id] = happyness;
	}
	string s1, s2;
	int id1, id2;
	int dis;
	for (int i = 0; i < K; i++){
		cin >> s1 >> s2 >> dis;
		id1 = stringToInt[s1];
		id2 = stringToInt[s2];
		node n1 = newNode(id2, dis);
		node n2 = newNode(id1, dis);
		G[id1].push_back(n1);
		G[id2].push_back(n2);
	}


	dijsktra(0);

	int end = stringToInt["ROM"];
	DFS(end);


	printf("%d %d %d %d\n", num_path, d[end], optValue, optAvgValue);

	printf("%s", intToString[0].c_str());

	for (int i = path.size() - 1; i >= 0; i--){
		printf("->%s", intToString[path[i]].c_str());
	}
	printf("\n");

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值