#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXV = 1020; //最大顶点数,此处要注意最大顶点数是居民点和加油站之和
const int INF = 1000000000; //无穷大
//n为顶点数,m为加油站数,k为边数,DS为服务范围,G为邻接矩阵
//d[]记录最短距离
int n, m, k, DS, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV] = {false}; //vis[i] == true表示顶点i已访问,初值均为false
//Dijkstra算法求所有顶点到起点s的最短距离
void Dijkstra(int s) //s为起点
{
memset(vis, false, sizeof(vis)); //初始化vis[]数组为false,每一轮都要初始化
fill(d, d + MAXV, INF); //初始化d[]
d[s] = 0;
for(int i = 0; i < n + m; i++) //循环n + m次
{
int u = -1, MIN = INF; //u使d[u]最小,MIN存放该最小的d[u]
for(int j = 1; j <= n + m; j++) //找到未访问顶点中d[]最小的
{
if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
}
//找不到小于INF的d[u],说明剩下的顶点和起点s不连通
if(u == -1)
return;
vis[u] = true; //标记u为已访问
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[]转换为数字,若str是数字,则返回本身;否则返回去掉G之后的数加上n
int getID(char str[])
{
int i = 0, len = strlen(str), ID = 0;
while(i < len)
{
if(str[i] != 'G') //只要不是G,就转换为数字
{
ID = ID * 10 + (str[i] - '0');
}
i++;
}
if(str[0] == 'G')
return n + ID; //首位是G,返回n + ID
else
return ID; //首位不是G,返回ID
}
int main()
{
scanf("%d%d%d%d", &n, &m, &k, &DS);
int u, v, w;
char city1[5], city2[5];
fill(G[0], G[0] + MAXV * MAXV, INF); //初始化边权
for(int i = 0; i < k; i++)
{
scanf("%s %s %d", city1, city2, &w); //以字符串形式读入城市编号
u = getID(city1); //将字符串转换为数字id
v = getID(city2);
G[u][v] = G[v][u] = w; ///边权
}
//ansDis存放最大的最短距离
//ansAvg存放最小平均距离,ansID存放最终加油站ID
double ansDis = -1, ansAvg = INF;
int ansID = -1;
for(int i = n + 1; i <= n + m; i++) //枚举所有加油站
{
double minDis = INF, avg = 0; //minDis为最短距离,avg为平均距离
Dijkstra(i); //进行Dijkstra算法,求出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) //存在距离大于DS的居民房,跳过该加油站
{
continue;
}
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\n", ansDis, ansAvg);
}
return 0;
}
【PAT A1072】Gas Station(Dijkstra算法)
最新推荐文章于 2024-10-15 19:28:18 发布