A1072 Gas Station (30point(s))
题意
给出加油站、房子之间的距离,最大服务距离,要求输出最优的加油站,如果没有符合条件(全部房子在服务范围内)的加油站则输出 No Solution
最优就是这个加油站到房子的距离最小的最大,到所有房子的平均距离最小,id最小,三个条件优先级逐个递减。
思路
Dijkstra算法,算是写得比较熟了。
总结
Sample Input1:
4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2
Sample Output1:
G1
2.0 3.3
Sample Input2:
2 1 2 10
1 G1 9
2 G1 20
Sample Output2:
No Solution
#include"bits/stdc++.h"
using namespace std;
int n;
const int maxn = 1000+10+10;
int G[maxn][maxn];
int dis[maxn];
int vis[maxn];
// gas station: n+1...n+m+1
int getId(const string& s) {
if(s[0] == 'G') {
return stoi(s.substr(1,s.size()-1))+n;
} else
return stoi(s);
}
struct Node {
bool operator()(int t1,int t2) {
return dis[t1] >= dis[t2];
}
};
void diskj(int startId,int num) {
fill(dis,dis+maxn,INT32_MAX);
fill(vis,vis+maxn,0);
dis[startId] = 0;
priority_queue<int,vector<int>,Node> q;
q.push(startId);
for(int i=0; i<num; i++) {
int id;
while(true){
if(q.empty())
return;
if(vis[q.top()]){
q.pop();
continue;
}
id = q.top();
q.pop();
break;
}
vis[id] = 1;
for(int j=1;j<=num;j++){
if(vis[j] || G[id][j] == INT32_MAX) continue;
int ed = dis[id] + G[id][j];
if(ed < dis[j]){
dis[j] = ed;
q.push(j);
}
}
}
}
bool better(int ans_id,double ans_d,double ans_avg,int id,double d,double avg){
if(ans_d == d){
if(ans_avg == avg)
return id < ans_id;
return avg < ans_avg;
}
return d > ans_d;
}
int main() {
// freopen("input.txt","r",stdin);
int m,k,D;
cin >> n >> m >> k >> D;
fill(G[0],G[0]+maxn*maxn,INT32_MAX);
for(int i=0; i<k; i++) {
string s1,s2;
int dt;
cin >> s1 >> s2 >> dt;
int t1 = getId(s1);
int t2 = getId(s2);
G[t1][t2] = G[t2][t1] = dt;
}
int ans_id = -1; double ans_d = -1,ans_avg = 0; // d>avg>id
for(int i=1; i<=m; i++) {
int id = i+n;
diskj(id,n+m);
double d = INT32_MAX, avg = 0;
int d_max = -1;
for(int j=1;j<=n;j++){
d = min(d,dis[j]*1.0); avg += dis[j]; d_max = max(d_max,dis[j]);
}
avg /= n;
if(d_max <= D && better(ans_id,ans_d,ans_avg,id,d,avg)){
ans_id = id; ans_d = d; ans_avg = avg;
}
}
//it must guarantee that all the houses are in its service range.
if(ans_id == -1)
cout << "No Solution" << endl;
else
printf("G%d\n%.1f %.1f\n",ans_id-n,ans_d,ans_avg);
}