/*************************
题意:
给出一个图
里面有居民区1-N,也有加油站G1-GN
选择一个加油站
要求该加油站 到居民区的最小距离 最大,并且各距离都在ds范围内
如果最小距离相同, 则要求 到各居民区的平均距离 最小
还相等,则要求序号最小
************************/
/***********************
简单的Dijkstra
以每个加油站做起点,做一次dijkstra
然后检查上述的4个条件去选择一个最合适的加油站
写的时候要谨慎,因为dijstra这种非常容易写错。
注意点:
1. 注意居民区序号是1-N, 加油站序号是G1-GM
2. 故我们可以把加油站的序号设为 N+i,i是Gi中的i,即可以少开一些数组
*************************/
/***********************
笔记:
*********************/
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
using namespace std;
#define M 1200
#define INF 0x7ffffff
struct Ans{
int index;
int mindis;
double avgdis;
};
bool cmp(Ans a,Ans b){
if(a.mindis > b.mindis)
return true;
else if(a.mindis == b.mindis){
if(a.avgdis < b.avgdis)
return true;
else if(a.avgdis == b.avgdis)
return a.index <b.index;
else return false;
}
else return false;
}
vector<Ans> ans;
int dis[M][M];
int n,m,k,ds;
void dijk(int s){
int d[M], v[M], i, j;
for(i = 1; i <=n + m;i++){
d[i] = INF;
v[i] = 0;
}
d[s] = 0;
int dismin,select;
for(i = 1;i <= n + m;i++){
dismin = INF;
for(j = 1; j <= n + m; j++){
if(!v[j] && d[j] < dismin){
dismin = d[j];
select = j;
}
}
if(dismin == INF )
break;
v[select] = 1;
for(j = 1;j <= n + m; j++){
if(!v[j] && d[select] + dis[select][j] < d[j]){
d[j] = d[select] + dis[select][j];
}
}
}
dismin = INF;
int sum=0;
for(i = 1;i <= n; i++){
if(d[i] > ds)
break;
if(d[i]<dismin){
dismin = d[i];
}
sum += d[i];
}
Ans a;
if(i == n+1){
a.avgdis = double(sum)/double(n);
a.index = s-n;
a.mindis = dismin;
ans.push_back(a);
}
}
int main(){
int i;
string strs,stre;
int s,e,d,j;
scanf("%d%d%d%d",&n,&m,&k,&ds);
for(i=1;i<=n+m;i++)
for(j=1;j<=n+m;j++){
if(i != j)
dis[i][j] = INF;
else dis[i][j] = 0;
}
for(i=0;i<k;i++){
cin>>strs>>stre>>d;
if(strs[0] == 'G'){
s = n + atoi(strs.substr(1).c_str());
}
else s = atoi(strs.c_str());
if(stre[0] == 'G'){
e = n + atoi(stre.substr(1).c_str());
}
else e = atoi(stre.c_str());
if(d < dis[s][e]){
dis[s][e] = d;
dis[e][s] = d;
}
}
for(i = n + 1; i <= n + m;i++){
s = i;
dijk(s);
}
if(ans.size() == 0){
cout<<"No Solution"<<endl;
}
else{
sort(ans.begin(),ans.end(),cmp);
printf("G%d\n%.1lf %.1lf\n",ans[0].index,double(ans[0].mindis),ans[0].avgdis);
}
return 0;
}
PAT 1072. Gas Station (30) dijkstra应用
原创
©著作权归作者所有:来自51CTO博客作者breakDawn的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
PAT 甲级 1072 Gas Station (30 分)(dijstra)
PAT 甲级 1072 Gas Station (30 分)(dijstra)
i++ #include 最短路径 ios #define -
*PAT_甲级_1072 Gas Station (30point(s)) (C++)【Dijkstra/字符串截取/与数字相互转换】
1,题目描述2,思路3,AC代码
PAT 甲级 C++ 1072 Dijkstra 字符串截取