#include<bits/stdc++.h>
using namespace std;
const int maxn = 1020;
const int INF = 100000;
int n, m, k, Ds, G[maxn][maxn];
int d[maxn];
bool vis[maxn] = {false};
void dijkstra(int s)
{
fill(d, d + maxn, INF);
fill(vis, vis + maxn, false); //dijkstra要计算多次,所以每次都要置0
d[s] = 0;
for(int i = 0; i < n + m; i++) //循环n+m次
{
int u = -1, MIN = INF;
for(int j = 1; j <= n + m; j++)
{
if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 1; v <= n + m; v++)
{
if(vis[v] == false && G[u][v] != INF)
{
if(d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
}
}
}
}
}
//将str[]转成数字,如果ste是数字,返回本身,否则返回去掉G之后的数加上n
int getID(char str[])
{
int i = 0, len = strlen(str), ID = 0;
while(len--)
{
if(str[i] != 'G') //只要不是G就转成数字
{
ID = ID * 10 + (str[i] - '0');
}
i++;
}
if(str[0] == 'G') return ID + n;
else return ID;
}
int main()
{
scanf("%d%d%d%d",&n, &m, &k, &Ds);
char str1[5], str2[5];
int u, v, w;
fill(G[0], G[0] + maxn * maxn, INF);
for(int i = 0; i < k; i++)
{
scanf("%s %s %d", str1, str2, &w);
// scanf("%s%s%d", str1, str2, &w); 也可以
u = getID(str1);
v = getID(str2);
G[u][v] = G[v][u] = w;
}
double ansDis = -1, ansAvg = INF; //ans存放最大的最短距离,ansAvg存放最小平均距离,ansID存放最终加油站ID
int ansID = -1;
for(int i = n + 1; i <= n + m; i++) //枚举所有加油站
{
double minDis = INF, avg = 0; //misDis为最大的最近距离,avg为平均距离
dijkstra(i); //求出d[]数组
for(int j = 1; j <= n; j++) //枚举所有居民房,求出minDis和avg
{
if(d[j] > Ds) //存在距离大于Ds的居民房,直接跳出
{
minDis = -1;
break;
}
if(d[j] < minDis) minDis = d[j]; //更新最大的最近距离
avg += 1.0 * d[j] / n; //获取平均距离
}
if(minDis == -1) continue; //存在距离大于Ds的居民房,跳过该加油站
if(minDis > ansDis) //更新最大的最近距离
{
ansID = i;
ansDis = minDis;
ansAvg = avg;
}
else if(minDis == ansDis && avg < ansAvg) //更新平均最小距离
{
ansID = i;
ansAvg = avg;
}
}
if(ansID == -1) printf("No Solution\n");
else
{
printf("G%d\n", ansID - n);
printf("%.1f %.1f", ansDis, ansAvg);
}
return 0;
}
A1072(加油站)
最新推荐文章于 2020-11-09 18:27:56 发布