题意
- 这个题读起来有点烦,是这样的,首先有
N
个居民房和M
个加油站,每个加油站都对应着一个最小距离和平均距离,加油站的最小距离是指从他到其他所有居民房的最短路径的最小值(从N
条最短路径里面选),现在让你选择一个加油站,首先他到所有居民房的最短路径均不能大于服务范围(每个加油站都一样),其次他的最小距离在所有加油站的最小距离中最大(从M
个加油站中选),若不唯一,选择平均距离最小的,若再不唯一,选择编号最小的。若没有一个加油站能服务到所有居民房,那么输出No Solution
注意
- 因为算每个加油站的最小距离和平均距离需要知道最短路径长度,所以每个加油站都要来一遍
dijkstra
,每算出来一个加油站到一个居民房的最短路径(S
集新元素)就更新这个加油站的最小距离和平均距离,同时也要判断是否小等于服务范围,不然这个加油站的dijkstra
直接结束。 - 把平均距离先按照距离和处理,最后再除。
- 把每个加油站的信息算完以后,再在加油站之间比这俩数,不满足服务范围的加油站不用考虑。
- 加油站编号还要处理一下。
代码
#include <iostream>
#include <algorithm>
#include <climits>
#include <string>
using namespace std;
const int Nmax = 1011;
int N, M, K, Ds;
int road[Nmax][Nmax];
int dist[Nmax];
bool S[Nmax];
bool isM[11];
int minRoad[11];
int avgRoad[11];
void DIJKSTRA()
{
fill(isM, isM + 11, false);
fill(minRoad, minRoad + 11, INT_MAX);
fill(avgRoad, avgRoad + 11, 0);
for (int i = 1; i <= M; i++)
{
fill(S, S + Nmax, false);
fill(dist, dist + Nmax, INT_MAX);
dist[i + N] = 0;
for (int k = 1; k <= N + M; k++)
{
int min = INT_MAX;
int u;
for (int j = 1; j <= N + M; j++)
{
if (!S[j] && dist[j] < min)
{
min = dist[j];
u = j;
}
}
if (dist[u] > Ds && u <= N)
{
isM[i] = true;
break;
}
S[u] = true;
if (u <= N)
{
avgRoad[i] += dist[u];
if (dist[u] < minRoad[i])
minRoad[i] = dist[u];
}
for (int j = 1; j <= N + M; j++)
{
if (!S[j] && road[u][j] != INT_MAX)
{
if (dist[u] + road[u][j] < dist[j])
{
dist[j] = dist[u] + road[u][j];
}
}
}
}
}
}
void select()
{
int opt = 0;
int max = -1;
for (int i = 1; i <= M; i++)
{
if (!isM[i])
{
if (minRoad[i] > max)
{
max = minRoad[i];
opt = i;
}
else if (minRoad[i] == max && avgRoad[i] < avgRoad[opt])
{
opt = i;
}
}
}
if (opt == 0)
{
cout << "No Solution";
return;
}
double minR, avgR;
minR = minRoad[opt];
avgR = (double)(avgRoad[opt]) / (double)(N);
cout << "G" << opt << endl;
printf("%.1f %.1f", minR, avgR);
}
int main()
{
cin >> N >> M >> K >> Ds;
string r1, r2;
int r3, r4;
fill(road[0], road[0] + Nmax*Nmax, INT_MAX);
for (int i = 0; i < K; i++)
{
cin >> r1 >> r2;
if (r1[0] == 'G')
r3 = atoi(r1.substr(1, r1.size() - 1).c_str()) + N;
else
r3 = atoi(r1.c_str());
if (r2[0] == 'G')
r4 = atoi(r2.substr(1, r2.size() - 1).c_str()) + N;
else
r4 = atoi(r2.c_str());
cin >> road[r3][r4];
road[r4][r3] = road[r3][r4];
}
DIJKSTRA();
select();
return 0;
}