题目大意:要确定一个加油站,到所有居民房的最短距离最大,如果不唯一,输出平均距离最短的加油站,如果还不唯一,输出id小的。
注意:所有的居民房都必须要服务范围内!
假设有m个加油站,需要跑m次最短路,最后注意答案输出的精度。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1015;
int n,m,k,d;
int g[N][N],dis[N];
bool st[N];
void dijkstra(int s)
{
memset(dis,0x3f,sizeof dis);
memset(st,false,sizeof st);
dis[s] = 0;
for(int i = 1; i <= n + m; i ++)
{
int u = -1;
for(int j = 1; j <= n + m; j ++)
if(!st[j] && (u == -1 || dis[u] > dis[j])) u = j;
st[u] = true;
for(int j = 1; j <= m + n; j ++) dis[j] = min(dis[j],dis[u] + g[u][j]);
}
}
int main()
{
cin >> n >> m >> k >> d;
memset(g,0x3f,sizeof g);
for(int i = 0; i < k; i ++)
{
string a,b;int c;
int x,y;
cin >> a >> b >> c;
if(a[0] == 'G') x = stoi(a.substr(1)) + n;
else x = stoi(a);
if(b[0] == 'G') y = stoi(b.substr(1)) + n;
else y = stoi(b);
g[x][y] = g[y][x] = c;
}
int idx = 0,mindis = -1e9,ans = 1e9;
for(int i = 1; i <= m; i ++)
{
int res = 0,cnt = 0,last = 1e9;
dijkstra(i + n);
for(int j = 1; j <= n; j ++)
{
if(dis[j] <= d)
{
res += dis[j],cnt ++;
last = min(dis[j],last);
}
}
if(cnt != n) continue;
if(last > mindis || last == mindis && ans > res)
{
idx = i;ans = res;mindis = last;
}
}
if(idx == 0) puts("No Solution");
else printf("G%d\n%.1lf %.1lf",idx,mindis * 1.0,ans * 1.0 / n + 1e-6);
return 0;
}