对每个候选的加油站点都用一次Dijkstra,根据题意找出最符合要求的站点。
- 注意一些初始值的设置,比如
bestLocation
初始值-1,表示No Solution; shortest
记录加油站到住宅的最小距离,初始值为0,保证了当Dijkstra找到了第一个可行的站点时能够更新;- 因为要求当最小距离
shortest
相等时,取平均距离最小的,亦即总距离totalDis
最小,所以totalDis
的初始值为inf。
总而言之,题目要求什么,各变量初始值就反其道而行之,以确保结果能够得到正确更新。
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
const int inf = 0x7fffffff;
int numHouse, numCandidate, numRoad, range;
int map[1024][1024];
int minDistance[1024]; //Dijkstra中用来保存当前从起点到各个地点的最短距离,各地点起始距离为int最大值,仅起点起始距离为零
bool visited[1024];
//获取某个地点的编号,将带G前缀的地点放到数组末尾
int getIndex(string pos) {
if (pos[0] == 'G') {
string temp = pos.substr(1, pos.size() - 1);
int offset = stoi(temp);
return offset + numHouse;
}
else return stoi(pos);
}
int main() {
cin >> numHouse >> numCandidate >> numRoad >> range;
fill(map[0], map[0] + 1024 * 1024, inf);
for (int i = 0; i < numRoad; i++) {
string s1, s2;
int dis, p1, p2;
cin >> s1 >> s2 >> dis;
p1 = getIndex(s1);
p2 = getIndex(s2);
map[p1][p2] = dis;
map[p2][p1] = dis;
}
int bestLocation = -1, shortest = 0, totalDis = inf;
for (int k = 1; k <= numCandidate; k++) {
fill(minDistance, minDistance + 1024, inf);
fill(visited, visited + 1024, false);
minDistance[k + numHouse] = 0;
for (int i = 1; i <= numHouse + numCandidate; i++) {
int u = -1, minDis = inf;
for (int j = 1; j <= numHouse + numCandidate; j++) {
if (!visited[j] && minDis > minDistance[j]) {
minDis = minDistance[j];
u = j;
}
}
if (u == -1) {
break;
}
visited[u] = true;
for (int v = 1; v <= numHouse + numCandidate; v++) {
if (!visited[v] && map[u][v] != inf) {
if (map[u][v] + minDis < minDistance[v]) {
minDistance[v] = map[u][v] + minDis;
}
}
}
}
int total = 0, min = inf, farthest = 0;
//找出最远的和最近的距离,只有最远的距离在服务范围内并且最近的距离小于当前最小的距离时更新bestLocation
for (int i = 1; i <= numHouse; i++) {
if (minDistance[i] < min) {
min = minDistance[i];
}
if (farthest < minDistance[i]) {
farthest = minDistance[i];
}
total += minDistance[i];
}
if (farthest <= range && (min > shortest ||
min == shortest && total < totalDis ||
min == shortest && total == totalDis && bestLocation > k)) {
shortest = min;
totalDis = total;
bestLocation = k;
}
}
if (shortest == 0) {
printf("No Solution");
} else printf("%s\n%.1f %.1f\n", ("G" + to_string(bestLocation)).c_str(), (double)shortest, (double)totalDis / numHouse);
}