pat甲级1072. Gas Station (30)

欢迎访问我的pat甲级题解目录哦https://blog.csdn.net/richenyunqi/article/details/84981078

题目描述

pat甲级1072. Gas Station (30)_第1张图片

题意分析

求出符合下列要求的加油站:

  1. 到所有住宅区的距离都在服务范围之内
  2. 在所有加油站到最近的住宅区的距离最远
  3. 如果有多个加油站符合要求选择到所有住宅区平均距离最小的
  4. 如果仍有多个加油站符合要求选择编号最小的

算法设计

首先,加油站按G1、G2……等形式编号可以把加油站的编号映射为N+1、N+2……。由于加油站最多有10个,可以采取暴力搜索的方法,对每一个加油站都使用一次Dijkstra算法,求出该加油站到所有住宅区的最短距离,然后找出符合要求的加油站即可。

使用邻接表版的c++代码

#include
using namespace std;
struct Edge{//边的类
    int v,length;
};
int N,M,K,Ds,station=-1;//station表示符合要求的加油站编号
double minDis=-1,avgDis=1e9;//到最近的住宅区距离、到所有住宅区的平均距离
vectorgraph[1015];//图
int dis[1015];//到住宅区和加油站的最短距离
bool visit[1015];//是否已访问过
int trans(const string&s){//将加油站的“Gi”形式的编号转换成N+i,住宅区的编号不变
    if(s[0]=='G')
        return stoi(s.substr(1))+N;
    else
        return stoi(s);
}
void Dijkstra(){
    for(int j=0;jdis[v]+e.length)
                dis[e.v]=dis[v]+e.length;
    }
}
int main(){
    scanf("%d%d%d%d",&N,&M,&K,&Ds);
    for(int i=0;i>s1>>s2>>k1;
        int k2=trans(s1),k3=trans(s2);
        graph[k2].push_back({k3,k1});
        graph[k3].push_back({k2,k1});
    }
    for(int i=N+1;i<=N+M;++i){//对M个加油站使用M次Dijkstra算法
        fill(dis,dis+N+M+1,INT_MAX);
        dis[i]=0;
        fill(visit,visit+M+N+1,false);
        Dijkstra();
        double currentMindis=INT_MAX*1.0,currentAvgDis=0.0;//记录当前加油站到最近的住宅区距离、到所有住宅区的平均距离
        bool flag=true;//表示到所有住宅区的距离是否都在服务范围内
        for(int j=1;j<=N&&flag;++j)//更新相应变量信息
            if(j!=i&&dis[j]<=Ds){
                currentMindis=min(currentMindis,dis[j]*1.0);
                currentAvgDis+=dis[j]*1.0;
            }
            else if(dis[j]>Ds)
                flag=false;
        currentAvgDis/=N;
        if(flag&&(currentMindis>minDis||(currentMindis==minDis&¤tAvgDis

邻接矩阵版c++代码

#include
using namespace std;
int N,M,K,Ds,station=-1;//station表示符合要求的加油站编号
double minDis=-1,avgDis=1e9;//到最近的住宅区距离、到所有住宅区的平均距离
int graph[1015][1015],dis[1015];//图、到住宅区和加油站的最短距离
bool visit[1015];//是否已访问过
int trans(const string&s){//将加油站的“Gi”形式的编号转换成N+i,住宅区的编号不变
    if(s[0]=='G')
        return stoi(s.substr(1))+N;
    else
        return stoi(s);
}
void Dijkstra(){
    for(int j=0;jdis[v]+graph[v][i])
                dis[i]=dis[v]+graph[v][i];
    }
}
int main(){
    scanf("%d%d%d%d",&N,&M,&K,&Ds);
    for(int i=0;i>s1>>s2>>k1;
        int k2=trans(s1),k3=trans(s2);
        graph[k2][k3]=graph[k3][k2]=k1;
    }
    for(int i=N+1;i<=N+M;++i){//对M个加油站使用M次Dijkstra算法
        fill(dis,dis+N+M+1,INT_MAX);
        dis[i]=0;
        fill(visit,visit+M+N+1,false);
        Dijkstra();
        double currentMindis=INT_MAX*1.0,currentAvgDis=0.0;//记录当前加油站到最近的住宅区距离、到所有住宅区的平均距离
        bool flag=true;//表示到所有住宅区的距离是否都在服务范围内
        for(int j=1;j<=N&&flag;++j)//更新相应变量信息
            if(j!=i&&dis[j]<=Ds){
                currentMindis=min(currentMindis,dis[j]*1.0);
                currentAvgDis+=dis[j]*1.0;
            }
            else if(dis[j]>Ds)
                flag=false;
        currentAvgDis/=N;
        if(flag&&(currentMindis>minDis||(currentMindis==minDis&¤tAvgDis

 

你可能感兴趣的:(pat甲级)