解题思路:
用dijkstra算法计算出每个加油站到村庄的最短距离即可。
对于加油站的优先级:
1)保证距离最大的村庄在服务范围内
2)在1)下,保证距离最小的村庄离加油站最远
3)在2)下,保证平均距离最小
4)在3)下,保证id最小
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 1000 + 15;
const int INF = 0x3fffffff;
struct Edge
{
int from, to, w;
Edge(int u, int v, int w):from(u), to(v), w(w) {}
};
vector<Edge> edges;
vector<int> G[maxn];
int vis[11][maxn];
int d[11][maxn];
int avg[11];
int n, m, k;
int ds;
void dijkstra(int id, int s)
{
d[id][s] = 0;
for(;;)
{
int u = -1, MIN = INF;
for(int i = 1; i <= n+m; i++)
{
if(d[id][i] < MIN && !vis[id][i])
{
u = i;
MIN = d[id][i];
}
}
if(u == -1) break;
vis[id][u] = 1;
for(int i = 0; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
if(vis[id][e.to]) continue;
if(d[id][e.to] > d[id][e.from] + e.w)
d[id][e.to] = d[id][e.from]+e.w;
}
}
}
int ID(char* s)
{
if(s[0] != 'G')
{
int len = strlen(s), id = 0;
for(int i = 0; i < len; i++)
id = id * 10 + s[i]-'0';
return id;
}
else
{
int len = strlen(s), id = 0;
for(int i = 1; i < len; i++)
id = id*10 + s[i] - '0';
return n + id;
}
}
int main()
{
while(scanf("%d%d%d%d", &n, &m, &k, &ds) == 4)
{
for(int i = 0; i <= n+m; i++) G[i].clear();
for(int i = 0; i < k; i++)
{
int w;
char s1[10], s2[10];
scanf("%s%s%d", s1, s2, &w);
int u = ID(s1), v = ID(s2);
edges.push_back(Edge(u, v, w));
edges.push_back(Edge(v, u, w));
G[u].push_back(edges.size()-2);
G[v].push_back(edges.size()-1);
}
memset(vis, 0, sizeof(vis));
memset(avg, 0, sizeof(avg));
for(int i = 0; i < 11; i++)
for(int j = 0; j <= n+m; j++)
d[i][j] = INF;
for(int i = n+1; i <= n+m; i++)
dijkstra(i-n, i);
int ans = 0;
int ansMind, ansAvg;
for(int i = 1; i <= m; i++)
{
int maxd = 0, mind = INF;
for(int j = 1; j <= n; j++)
{
avg[i] += d[i][j];
maxd = max(d[i][j], maxd);
mind = min(d[i][j], mind);
}
if(maxd <= ds)
{
if(ans == 0)
{
ans = i;
ansMind = mind;
ansAvg = avg[i];
}
else if(mind > ansMind)
{
ans = i;
ansMind = mind;
ansAvg = avg[i];
}
else if(mind == ansMind && ansAvg > avg[i])
{
ans = i;
ansMind = mind;
ansAvg = avg[i];
}
}
}
if(ans) printf("G%d\n%.1f %.1f\n", ans, ansMind*1.0, ansAvg*1.0/(n*1.0));
else printf("No Solution\n");
}
return 0;
}