原题链接:
注意点:
1.该题目在AcWing上有近似题,但AcWing上的测试点好像更严一些,我这份代码在AcWing上没有AC,之后有时间再做研究,下面贴上AcWing链接:
https://www.acwing.com/problem/content/description/1560/
2.注意dijkstra中的初始化,我第一次写的时候错误的在这个函数内部初始化了,这种错误初始化错误要尽量避免,因为这种错误出现后,编译器很难发现,debug困难。
for (int i = 1; i <= M; i++) {
able[i] = true;
minDist[i] = INF;
avgDist[i] = INF;
}
3.代码思路就是dijkstra算法,算法模板思路就是初始化 -> 选点 -> 更新,选点+更新需要遍历多次。
代码:
#include <iostream>
#include <vector>
#include <utility>
#include <string>
#include <cstring>
#include <math.h>
#include <iomanip>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f3f3f3f
int N, M, K, D;
vector<pair<int, int> > mp[1011];
int cvs(string str) {
if (str[0] == 'G') {
str.erase(str.begin());
return stoi(str) + N;
}
return stoi(str);
}
int dist[1011];
int vis[1011];
double minDist[11];
double avgDist[11];
bool able[11];
void dijkstra(int g) {
memset(dist, 0, sizeof dist);
memset(vis, 0, sizeof vis);
for (int i = 1; i <= N + M; i++) {
dist[i] = INF;
}
vis[g] = 1;
for (int i = 0; i < mp[g].size(); i++) {
dist[mp[g][i].first] = mp[g][i].second;
}
int sumDist = 0;
for (int j = 0; j < N + M - 1; j++) {
//选点
int minD = INF, minIndex = 0;
for (int i = 1; i <= N + M; i++) {
if (!vis[i]) {
if (dist[i] < minD) {
minD = dist[i];
minIndex = i;
}
}
}
//更新
vis[minIndex] = 1;
if (minD > D && minIndex <= N) {//超出服务范围
able[g-N] = false;
return;
}
if (minIndex <= N) {
minDist[g-N] = min(minDist[g-N], (double)minD);
sumDist += minD;
}
for (int i = 0; i < mp[minIndex].size(); i++) {
if (!vis[mp[minIndex][i].first]&&dist[mp[minIndex][i].first] > dist[minIndex] + mp[minIndex][i].second) {
dist[mp[minIndex][i].first] = dist[minIndex] + mp[minIndex][i].second;
}
}
}
avgDist[g - N] = (double)sumDist / N;
return;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N >> M >> K >> D;
for (int i = 0; i < K; i++) {
string str1, str2;
cin >> str1 >> str2;
int u, v;
u = cvs(str1);
v = cvs(str2);
int w;
cin >> w;
mp[u].emplace_back(make_pair(v, w));
mp[v].emplace_back(make_pair(u, w));
}
for (int i = 1; i <= M; i++) {
able[i] = true;
minDist[i] = INF;
avgDist[i] = INF;
}
for (int i = 1; i <= M; i++) {
dijkstra(N+i);
}
int tempMax = 0;
int ans = 0;
for (int i = 1; i <= M; i++) {
if (able[i] == true) {
if (minDist[i] >tempMax) {
ans = i;
tempMax = minDist[i];
}
else if (minDist[i] == tempMax) {
if (avgDist[i] < avgDist[ans]) {
ans = i;
}
}
}
}
if (ans == 0) {
cout << "No Solution" << endl;
}
else {
cout << "G" << ans << endl;
cout << fixed << setprecision(1) << minDist[ans];
cout << " ";
cout << fixed << setprecision(1) << avgDist[ans];
}
return 0;
}