[PAT] A1072 Gas Station

最短路径

题目大意

从m个加油站里面选取1个站点,让它和离它最近的居民区距离最远,并且没有超出服务范围ds之内。如果有很多个最远的加油站,输出距离所有居民区距离平均距离最小的那个。如果平均值还是一样,就输出加油站编号最小的那个。

思路

Dijkstra算法。注意每次调用Dijkstra都要初始化。
因为加油站之间也是彼此有路连接的,所以最短路径计算的时候也要把加油站算上。因此考虑将加油站和居民点放在一起,用Dijkstra时循环的范围时1~n+m。可以根据输入的是G还是数字来判断,如果是数字就令编号为他自己,如果是G开头的,编号设为n+G后面的数字。
我是先针对每个加油站调用一次Dijkstra,将满足可连通、没有超出服务范围的所有加油站及各项参数(最近点的距离、平均距离、加油站编号)存在另一个结构体中,再统一判断求最优解。(因为数据量<=10,我就直接图方便写了个排序。最近点距离较远->平均距离较短->加油站编号较小)

坑点集中在最后一个测试点4:
(1)加油站和居民点的输入按照string,然后转成数字时要注意它不仅是1位数,可能是多位数。(str.erase(str.begin()+x);中参数是迭代器!)
(2).1f%的输出会自动四舍五入,不用+0.05。

AC代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define N 1020
#define INF 100000000
struct way {
    double dis, min;
    int index;
}ways[12];
int numways = 0;
struct node {
    int v, distance;
};
vector<node>Adj[N];
int n, m;//1~n是居民点;n+1~n+m是加油站
int dis[N];
bool vis[N] = { false };
void Dijkstra(int s) {
    int i, j;
    for (i = 0;i < N;i++) {
        dis[i] = INF;
        vis[i] = false;
    }
    dis[s] = 0;
    for (i = 0;i < n + m;i++) {
        int min = INF, u = -1;
        for (j = 1;j <= n + m;j++) {
            if (min > dis[j] && vis[j] == false) {
                min = dis[j];
                u = j;
            }
        }
        if (u == -1)return;
        vis[u] = true;
        for (j = 0;j < Adj[u].size();j++) {
            int v = Adj[u][j].v;
            if (vis[v] == false && dis[v] > dis[u] + Adj[u][j].distance) {
                dis[v] = dis[u] + Adj[u][j].distance;
            }
        }
    }
}
bool cmp(way a, way b) {
    if (a.min != b.min)return a.min > b.min;
    else if (a.dis != b.dis)return a.dis < b.dis;
    else return a.index < b.index;
}
int strtoint(string a) {
    int ans = 0;
    for (int i = 0;i < a.size();i++)
        ans = ans * 10 + a[i] - '0';
    return ans;
}
int main() {
    int i, j, k, dmax;
    scanf("%d%d%d%d", &n, &m, &k, &dmax);
    for (i = 0;i < k;i++) {
        int p1, p2, dist;
        string s_p1, s_p2;
        cin >> s_p1 >> s_p2 >> dist;      
        if (s_p1[0] == 'G') {
            s_p1.erase(s_p1.begin());
            p1 = strtoint(s_p1) + n;
        }
        else p1 = strtoint(s_p1);
        if (s_p2[0] == 'G') {
            s_p2.erase(s_p2.begin());
            p2 = strtoint(s_p2) + n;
        }
        else p2 = strtoint(s_p2);
        node temp;
        temp.distance = dist;
        temp.v = p1;Adj[p2].push_back(temp);
        temp.v = p2;Adj[p1].push_back(temp);
    }
    for (i = n + m;i > n;i--) {
        Dijkstra(i);
        for (j = 1;j <= n;j++)
            if (dis[j] > dmax)break;
        if (j == n + 1) {//符合条件的路径存在
            ways[numways].index = i - n;
            int dmin = INF;
            for (k = 1;k <= n;k++) {//计算总路径长和最小路径值
                if (dmin > dis[k])dmin = dis[k];
                ways[numways].dis += dis[k];
            }
            ways[numways].min = dmin;
            ways[numways].dis = ways[numways].dis / n;
            numways++;
        }
    }
    if (numways == 0)printf("No Solution\n");
    else {
        sort(ways, ways + numways, cmp);//顺手写了个排序,其实duck不必。找最小值就好了~
        printf("G%d\n%.1f %.1f\n", ways[0].index, ways[0].min, ways[0].dis);
    }
    return 0;
}

原文链接: https://www.cnblogs.com/yue36/p/13335110.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    [PAT] A1072 Gas Station

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/368190

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午6:16
下一篇 2023年3月2日 下午6:16

相关推荐