1072.Gas Station

【題意】
        找一個到所有房屋最短距離最遠,平均距離最近,且覆蓋所有房屋的加油站

【思路】
        把住房和加油站都視作普通節點,對每個加油站用一次Dijkstra算法即可

【注意點】

        此題Dijkstra算法中可以不用遍歷到每個點,只要把所有房屋都訪問到了就可以了,即使有些加油站訪問不到或者超出了服務範圍也不要緊。


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
using namespace std;

#define MAXIMUM 0x0fffffff

int n,m,k,ds;
vector<bool> visited;
vector<int> dist;
vector<vector<int>> weight;

typedef struct{
	int index;
	int minDist;
	float avgDist;
}gasStation;

bool cmp(gasStation g1, gasStation g2){
	if(g1.minDist>g2.minDist){
		return 1;
	}
	else if(g1.minDist==g2.minDist && g1.avgDist<g2.avgDist){
		return 1;
	}
	else if(g1.minDist==g2.minDist && g1.avgDist==g2.avgDist && g1.index<g2.index){
		return 1;
	}
	else{
		return 0;
	}
}

int lable2index(string lable){
	int index = 0;

	if(lable[0]=='G'){
		for(int i=1; i<lable.length(); i++){
			index = index*10+lable[i]-'0';
		}
		index += n-1;
	}
	else{
		for(int i=0; i<lable.length(); i++){
			index = index*10+lable[i]-'0';
		}
		index--;
	}

	return index;
}

int main(int argc, char const *argv[])
{
	cin >> n >> m >> k >> ds;
	visited.resize(n+m);
	dist.resize(n+m);
	weight.resize(n+m,vector<int>(n+m));

	for(int i=0; i<n+m; i++){
		for(int j=0; j<=i; j++){
			if(i==j){
				weight[i][j] = 0;
			}
			else{
				weight[i][j] = weight[j][i] = MAXIMUM;
			}
		}
	}
	//0~n-1		:residential housing
	//n~n+m-1	:gas station
	for(int i=0; i<k; i++){
		string ends[2];
		int d,index[2];

		cin >> ends[0] >> ends[1] >> d;
		index[0] = lable2index(ends[0]);
		index[1] = lable2index(ends[1]);
		weight[index[0]][index[1]] = weight[index[1]][index[0]] = d;
	}
	
	vector<gasStation> stations;
	//Dijkstra
	for(int gasIndex=n; gasIndex<n+m; gasIndex++){
		visited.assign(n+m,0);
		dist.assign(n+m,MAXIMUM);
		visited[gasIndex] = 1;
		dist[gasIndex] = 0;
		bool valid = 1;
		int minDist = MAXIMUM;
		float avgDist = 0.0;
		
		int cnt = n;
		int index = gasIndex;
		//並不需要把每個節點都遍歷到,只需要把n個城市遍歷到即可
		while(cnt){
			int min = MAXIMUM;
			int nextIndex;
			for(int j=0; j<n+m; j++){
				if(!visited[j]){
					if(dist[index]+weight[index][j]<dist[j]){
						dist[j] = dist[index]+weight[index][j];
					}
					if(dist[j]<min){
						min = dist[j];
						nextIndex = j;
					}
				}
			}
			if(min>ds){
				valid = 0;
				break;
			}
			index = nextIndex;
			visited[index] = 1;
			//編號小於n的點代表住房
			if(index<n){
				cnt--;
				if(dist[index]<minDist){
					minDist = dist[index];
				}
				avgDist += dist[index];
			}
		}
		avgDist /= n;
		if(valid){
			gasStation tmp;
			tmp.index = gasIndex;
			tmp.minDist = minDist;
			tmp.avgDist = avgDist;
			stations.push_back(tmp);
		}
	}

	if(stations.empty()){
		cout << "No Solution";
	}
	else{
		sort(stations.begin(),stations.end(),cmp);
		cout << 'G' << stations[0].index-n+1 << endl;
		printf("%d.0 %.1f", stations[0].minDist, stations[0].avgDist);
	}

	system("pause");
	return 0;
}


發佈了99 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章