这个题的题目真的是好长好长,而且要理清的东西挺多的。不过后面的输出给了比较时候要用的数据的提示。
首先,我们要保证加油站到居民楼越远越好,靠的是min{加油站到剧名楼的距离}的大小,取大的。
然后min{}还相等,取avg{加油站到剧名楼的距离}的大小,取小的。
然后avg{}还相等,取编号小的。
这个题为了便于处理,我把编号连续化了,居民楼的编号排前面,加油站的接在后面。这样dijstra的算法能好写点。
理清了上面,后面都是传统的Dijstra算法了。。。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include "float.h"
#define MAX 11111
using namespace std;
int n,m,k,ds;
struct node{
int ed;
float dis;
};
vector <node> g[MAX];//
float dis[MAX];
bool isVis[MAX];
struct ansNode{
float avg;
int no;
float min;
ansNode(){avg = FLT_MAX;};
};
ansNode ans;
int str2int(string s){
int pos = 0;
int ans = 0;
int gasNum = 0;
if(s[0] == 'G'){
pos = 1;
gasNum = n;
}
for(;pos < s.size() ;pos++){
ans *= 10;
ans += int(s[pos] - '0');
}
return ans + gasNum;
}
void Init(){
for(int i = 0 ;i < MAX ;i++){
dis[i] = FLT_MAX;
isVis[i] = false;
}
}
void Dijstra(int root){
dis[root] = 0;
for(int i = 1 ; i <= n + m ;i++){
int min = INT_MAX;
int u = -1;
for(int j = 1 ; j <= n+m ;j++){
if(!isVis[j] && dis[j] < min){
min = dis[j];
u = j;
}
}
if(u == -1)
return;
isVis[u] = true;
for(int j = 0;j < g[u].size() ;j++){
int v = g[u][j].ed;
if(dis[v] > dis[u] + g[u][j].dis)
dis[v] = dis[u] + g[u][j].dis;
}
}
}
void printfNo(int a){
cout << "G" << a-n << endl;
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&ds);
string st,ed;
int d;
node t;
for(int i = 0 ;i < k ;i++){
cin >> st >> ed >> t.dis;
int n_ed = str2int(ed);
int n_st = str2int(st);
t.ed = n_ed;
g[n_st].push_back(t);
t.ed = n_st;
g[n_ed].push_back(t);
}
bool haveAns = false;
for(int i = n + 1 ;i <= n+m ; i++){
Init();
Dijstra(i);
float min = FLT_MAX;
float Sum = 0;
float avg;
bool tag = true;
for(int j = 1 ; j <= n ;j++){
if(dis[j] > ds){
tag = false;
break;
}
Sum += dis[j];
if(min > dis[j])
min = dis[j];
}
if(tag){
avg = Sum/float(n);
haveAns = true;
if(ans.min < min){
ans.no = i;
ans.avg = avg;
ans.min = min;
}
else if(ans.min == min && ans.avg > avg){
ans.no = i;
ans.avg = avg;
ans.min = min;
}
else if(ans.min == min && ans.avg == avg && ans.no > i){
ans.no = i;
ans.avg = avg;
ans.min = min;
}
}
}
if(haveAns){
printfNo(ans.no);
printf("%.01f %.01f\n",ans.min,ans.avg);
}
else
printf("No Solution\n");
return 0;
}