1072 Gas Station

本文详细解析了GasStation问题中的最短路径算法实现,采用Dijkstra算法计算每个候选加油站到所有房屋的最短路径,进而筛选出满足条件的最佳解决方案。文章提供了完整的代码示例,并讨论了平均路径计算的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:Gas Station

主要的考察点很明确就是图的最短路径,我的思路是这样,利用Dijkstra求出每个候选点到所有房屋的最短路径,每个候选点都找到最短路径中最短的那个,同时也计算出平均路程,然后根据这些最短路径和平均路径,选出符合题目要求的那个Solution。

注意点:这道题的给定的样例有点问题,平均路径的输出结果看起来是要四舍五入的,但是这样写最后一个测试点又通不过。

(PS:输出并没有要求四舍五入,但这个样例的误导就很难受)

代码:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxN = 1100;
int n,m,k,md,ds;
int graph[maxN][maxN];
struct Gas{
    int id;
    double minDis,avgDis;
    explicit Gas(int id,double minDis,double avgDis){this->id = id;this->minDis = minDis;this->avgDis = avgDis;}
};
vector<Gas> candidate;
auto cmp = [](Gas a,Gas b){return a.minDis == b.minDis ? (a.avgDis == b.avgDis ? a.id < b.id : a.avgDis < b.avgDis) : a.minDis > b.minDis;};
void dijkstra(int c){
    int marked[maxN]{0},dist[maxN]{0};
    for(int i = 1;i <= n+m;i++) dist[i] = graph[c][i];
    marked[c] = 1;
    for(int i = 1;i <= n+m;i++){
        int ks = -1,minV = INF;
        for(int j = 1;j <= n+m;j++){
            if(!marked[j] && dist[j] < minV) ks = j,minV = dist[j];
        }
        if(ks == -1) break;
        marked[ks] = 1;
        for(int j = 1;j <= n+m;j++){
            if(!marked[j]) dist[j] = min(dist[j],dist[ks] + graph[ks][j]);
        }
    }
    int sum{0},flag{0},minDis = INF;
    for(int i = 1;i <= n;i++){
        sum += dist[i];
        if(dist[i] > md) {flag = 1;break;}
        if(dist[i] < minDis) minDis = dist[i];
    }
    if(!flag){
        Gas gas(c-n,double(minDis),sum * 1.0 / n);
        candidate.push_back(gas);
    }
}
int main() {
    scanf("%d %d %d %d",&n,&m,&k,&md);
    memset(graph,0x3f,sizeof(graph));
    char v[5],w[5];
    while(k--){
        scanf("%s %s %d",v,w,&ds);
        int a = v[0] == 'G' ? n + atoi(v+1) : atoi(v);
        int b = w[0] == 'G' ? n + atoi(w+1) : atoi(w);
        graph[a][b] = graph[b][a] = ds;
    }
    for(int i = 1;i <= m;i++) dijkstra(n + i);
    if(candidate.empty()) printf("No Solution\n");
    else{
        sort(candidate.begin(),candidate.end(),cmp);
        Gas ans= candidate.front();
        printf("G%d\n%.1f %.1f\n",ans.id,ans.minDis,ans.avgDis);
    }
    return 0;
}

因为候选点很少(<=10),所里偷懒用了排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值