PAT----A1072 Gas Station (30point(s))

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); 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值