1072 Gas Station (30 分)难度: 中 / 知识点: Dijkstra + 枚举
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1072 Gas Station (30 分)难度: 中 / 知识点: Dijkstra + 枚举相关的知识,希望对你有一定的参考价值。
https://pintia.cn/problem-sets/994805342720868352/problems/994805396953219072
题目说的不清不楚,应该直接说要建一个加油站,候选位置有以下几个。没说建一个还是两个。
分析:
就是枚举每一个加油站的候选位置,求最短路。然后根据题意找到最优解即可。这里的话点很少,直接朴素版的Dijkstra。
注意: 加油站的候选位置编号是字符串,需要将其映射要数字。
还要注意精度问题,加一特别小的数保持精度。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+50;
int g[N][N],st[N],dist[N],n,m,k,d;
int get(string s)
{
if(s[0]=='G') return n+stoi(s.substr(1));
return stoi(s);
}
bool Dijkstra(int startx,int &temp_min,int &temp_sum)
{
memset(dist,0x3f,sizeof dist); dist[startx]=0;
memset(st,0,sizeof st);
for(int i=0;i<n+m;i++)
{
int t=-1;
for(int j=1;j<=n+m;j++) if(!st[j]&&(t==-1 || dist[j]<dist[t])) t=j;
st[t]=1;
for(int j=1;j<=n+m;j++) dist[j]=min(dist[j],dist[t]+g[t][j]);
}
temp_min=1e9,temp_sum=0;
for(int i=1;i<=n;i++)
{
if(dist[i]>d) return false;//超出距离的范围
temp_sum+=dist[i];
temp_min=min(temp_min,dist[i]);
}
return true;
}
int main(void)
{
cin>>n>>m>>k>>d;
memset(g,0x3f,sizeof g);
for(int i=0;i<k;i++)
{
string x,y;
int a,b,c; cin>>x>>y>>c;
a=get(x),b=get(y);
g[a][b]=g[b][a]=min(g[a][b],c);
}
int flag=0,minv=0,sum=1e9;
for(int i=n+1;i<=n+m;i++)//枚举每一个加油站
{
int temp_min=0,temp_sum=0;
if(!Dijkstra(i,temp_min,temp_sum)) continue;
if(temp_min>minv) flag=i,minv=temp_min,sum=temp_sum;
else if(temp_min==minv&&temp_sum<sum) flag=i,sum=temp_sum;
}
if(flag) printf("G%d\\n%.1lf %.1lf",flag-n,1.0*minv,sum*1.0/(n)+1e-7);
else puts("No Solution");
return 0;
}
以上是关于1072 Gas Station (30 分)难度: 中 / 知识点: Dijkstra + 枚举的主要内容,如果未能解决你的问题,请参考以下文章
PAT (Advanced Level) 1072. Gas Station (30)
1072 Gas Station (30point(s)) 需要二刷 *多源最短路径问题