A1087 All Roads Lead to Rome (30分)
一、技术总结
- 首先对于题意的理解,N个城市,M条无向边,现在给定某城市作为初始城市,然后一个城市作为终点城市,每条边都需要花费路费,同时每个城市具有幸福值,如果路费最少的有多条,就选择幸福值总和最高的一条,如果任然不唯一,就是选择平均幸福值最高的路径。
- 还有一点需要解决的问题是,城市代号全为字符串,也就意味着需要使用map,在int和string之间进行转换。
- 同时,这里提出了一个关于平均点权该如何记录和递归的问题,平均点权等于路径上的点权之和除以路径上顶点的数目。
- 推荐使用Djikstra+DFS,如下代码所示
- 题中初始起点的点权没有给出,因此计算平均点权是不算初始起点的。
二、参考代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 210;
const int INF = 0x3fffffff;
bool vis[MAXN] = {false};
int G[MAXN][MAXN], d[MAXN];
int weight[MAXN], w[MAXN];
int n ,m ,st;//n是顶点,m是边数,st是起点的编号
int numPath = 0, maxW = 0; //numPath是最短路径的条数,maxW是最短路径中的最大点权之和
double maxAvg = 0;//最大平均点权
vector<int> pre[MAXN];//前驱
vector<int> tempPath, path;//临时路径
map<string, int> cityToIndex;
map<int, string> indexToCity;
void Djikstra(int s){
fill(d, d+MAXN, 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[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(d[u] + G[u][v] == d[v]){
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v){
if(v == st){
tempPath.push_back(v);
numPath++;
int tempW = 0;
for(int i = tempPath.size() - 2; i >= 0; i--){
int id = tempPath[i];
tempW += weight[id];
}
double tempAvg = 1.0*tempW / (tempPath.size() - 1);//临时平均点权
if(tempW > maxW){
maxW = tempW;
maxAvg = tempAvg;
path = tempPath;
}else if(tempW == maxW && tempAvg > maxAvg){
//点权之和相同, 平均点权更大的
maxAvg = tempAvg;
path = tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for(int i = 0; i < pre[v].size(); i++){
DFS(pre[v][i]);
}
tempPath.pop_back();
}
int main(){
string start, c1, c2;
cin >> n >> m >> start;
cityToIndex[start] = 0;
indexToCity[0] = start;
for(int i = 1; i < n; i++){
cin >> c1 >> weight[i];
cityToIndex[c1] = i;
indexToCity[i] = c1;
}
fill(G[0], G[0]+MAXN*MAXN, INF);
for(int i = 0; i < m; i++){
cin >> c1 >> c2;
int num1 = cityToIndex[c1], num2 = cityToIndex[c2];
cin >> G[num1][num2];
G[num2][num1] = G[num1][num2];
}
Djikstra(0);
int rom = cityToIndex["ROM"];
DFS(rom);
printf("%d %d %d %d\n", numPath, d[rom], maxW, (int)maxAvg);
for(int i = path.size()-1; i >= 0; i--){
cout << indexToCity[path[i]];
if(i > 0) cout << "->";
}
return 0;
}
作者:睿晞
身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
曾有一个业界大牛说过这样一段话,送给大家:
“华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.