PAT | A1072 Gas Station

题目一开始没看清,排序条件应该是:(首先要保证max_dis <= d)
1.所有待选gas_station中min_dis最大的
2.min_dis相同时选择aver_dis最小的
3.aver_dis相同时选择编号最小的gas_station

#include <iostream>
#include <sstream>
#include <algorithm>
#include <climits>

using namespace std;

int G[1020][1020];
int dis[1020];
bool vis[1020] = {false};

struct returnType{
	double minDistance;
	double averDistance;
	bool canBeChoose;
};

returnType Dijkstra(int i,int n,int m,int d){
	returnType res;
	fill(vis,vis + 1020,false);
	fill(dis,dis + 1020,INT_MAX);
	dis[i] = 0;
	for(int j = 1;j <= n + m + 1;j++){
		if(G[i][j] < INT_MAX){
			dis[j] = G[i][j];
		}
 	}
	for(int j = 0;j < n + m;j++){
		int u = -1,MIN = INT_MAX;
		for(int q = 1;q <= n + m + 1;q++){ //找到未访问的顶点中dis[]最小的
			if(vis[q] == false && dis[q] < MIN){
				u = q;
				MIN = dis[q];
			}
		}
		//找不到小于INT_MAX的dis[u],说明剩下的顶点和起点i不连通
		if(u == -1){
			res.canBeChoose = false;
			return res;
		}
		vis[u] = true; // 标记u为已访问
		for(int v = 1;v <= n + m + 1;v++){
			// 如果v未访问 && u能到达v && 以u为中介点能使d[v]更优
			if(vis[v] == false && G[u][v] != INT_MAX && dis[u] + G[u][v] < dis[v]){
				dis[v] = dis[u] + G[u][v]; // 优化d[v]
			}
		}
	}
	double minDis = INT_MAX;
	double sumDis = 0;
	for(int j = 1;j <= n;j++){
		if(dis[j] > d){
			res.canBeChoose = false;
			return res;
		}
		sumDis += dis[j];
		if(dis[j] < minDis)
			minDis = dis[j];
	}
	double averDis = sumDis / n;
	res.canBeChoose = true;
	res.averDistance = averDis;
	res.minDistance = minDis;
	return res;
}

int main(){
	int n,m,k,d;
	// n : 房子总数
	// m : 加油站候选地数量
	// k : 道路总数
	// d : 加油站的最大服务距离
	scanf("%d %d %d %d",&n,&m,&k,&d);
	for(int i = 0;i < 1020;i++){
		for(int j = 0;j < 1020;j++)
			G[i][j] = INT_MAX;
	}
	for(int i = 0;i < k;i++){
		string h1,h2;
		int u,v,dist;
		h1.resize(10);
		h2.resize(10);
		scanf("%s %s %d",&h1[0],&h2[0],&dist);
		stringstream ss1,ss2;
		if(h1[0] == 'G'){
			h1.erase(h1.begin());
			ss1<<h1;
			ss1>>u;
			u += n;
		}else{
			ss1<<h1;
			ss1>>u;
		}
		if(h2[0] == 'G'){
			h2.erase(h2.begin());
			ss2<<h2;
			ss2>>v;
			v += n;
		}else{
			ss2<<h2;
			ss2>>v;
		}
		G[u][v] = dist;
		G[v][u] = dist;
	}
	double minDis = -1;
	double averDis;
	int gasStation;
	for(int i = 1;i <= m;i++){
		returnType temp = Dijkstra(i + n,n,m,d);
		if(temp.canBeChoose == true && temp.minDistance > minDis){
			gasStation = i;
			minDis = temp.minDistance;
			averDis = temp.averDistance;
		}else if(temp.canBeChoose == true && temp.minDistance == minDis && temp.averDistance < averDis){
			gasStation = i;
			minDis = temp.minDistance;
			averDis = temp.averDistance;
		}
	}
	if(minDis == -1){
		printf("No Solution");
	}else{
		printf("G%d\n%.1lf %.1lf",gasStation,minDis,averDis);
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值