PAT Gas Station 寻找最大的最小Dijkstra距离

题意:N个居民房,M个加油站待建点,k条无向边。从M个加油站中选一个,使该加油站距离最近的居民房尽可能远,且必须保证所有房子与该加油站的距离都不超过给定的服务范围DS。如果有多个最近距离相同的解,选择平均距离最小的,如果平均距离相同,选择编号最小的。

分析:

1.输入可能是整数或者是Gn,所以要用字符串读入,根据首字符是否为‘G’判断如何处理编号。居民房1~N,加油站N+1~N+M。

2.最短距离可以经过加油站,故Dijkstra算法顶点编号范围1~N+M。

3.遍历每个加油站,得到一个d数组,寻找其中最小的值与平均距离。所有加油站中,第一标尺的最短距离,第二标尺是平均距离,由于是从小到大遍历加油站,第三标尺编号可以不考虑。

4.在Dijkstra算法中寻找最小值,计算平均距离(保存在全局变量中),若有一个居民房距离大于服务范围DS,返回-3。主函数中获得的返回值为-3时,continue,跳过接下来的比较步骤。

#include
#include
#include
#include
#pragma warning(disable:4996)
using namespace std;
const int maxn = 1010;
const int INF = 100000;

struct Node {
	int id;
	int dis;
};
vectorAdj[maxn];
int d[maxn]; //d[0]用于存储平均最短路径
bool mark[maxn]; //用于标记是否已加入最短距离顶点集合
bool isgas[maxn];//用于区分是否是加油站
double avgdis;
int N, M, K, DS;

int Dijkstra(int s, int N,int N1)//N是城市总数,N1是城市加上加油站的总数
{
	memset(mark, 0, sizeof(mark));
	fill(d, d + maxn, INF);
	d[s] = 0;
	for (int i = 0; i < N1; i++)
	{
		int u = -1,min=INF;
		for(int j=1;j<=N1;j++)
			if (!mark[j]&&d[j] < min)
			{
				min = d[j];
				u = j;
			}
		if (u == -1) return -2; //表示图不连通
		cout << "u:" << u << endl;
		mark[u] = true;
		for (int j = 0; j < Adj[u].size(); j++)
		{
			int v = Adj[u][j].id;
			int distance = Adj[u][j].dis;
			if (!mark[v] && d[u] + distance < d[v])
			{
				d[v] = d[u] + distance;
			}
		}
	}
	int mindis = INF;
	int minid = -1;
	int sum = 0;
	for (int i = 1; i <= N; i++)
	{
		cout << d[i] << " ";
		if (d[i] > DS)
			return -3; //表示超过服务范围
		sum += d[i];
		if (d[i] < mindis)
		{
			mindis = d[i];
			minid = i;
		}
	}
	avgdis = (double)sum / N;
	cout << "avgdis:" << avgdis << endl;
	return mindis;
}
int getnum(char a[])
{
	int len = strlen(a);
	int num = a[0]-'0';
	for (int i = 1; i < len; i++)
	{
		num *= 10;
		num += a[i] - '0';
	}
	return num;
}

int main()
{
	
	while (scanf("%d%d%d%d", &N, &M, &K, &DS) != EOF)
	{
		for (int i = 0; i < maxn; i++)
			Adj[i].clear();
		for (int i = 0; i < K; i++)
		{
			char s1[10], s2[10];
			int v, w,dist;
			scanf("%s%s%d", s1, s2, &dist);
			if (s1[0] == 'G')
				v = N + s1[1] - '0';
			else v = getnum(s1);
			if (s2[0] == 'G')
				w = N + s2[1] - '0';
			else w = getnum(s2);
			//cout << v << " " << w << endl;
			Node tmp;
			tmp.id = v;
			tmp.dis = dist;
			Adj[w].push_back(tmp);
			tmp.id = w;
			Adj[v].push_back(tmp);
		}
		int gasid=-1, mindis = 0;
		double minavg = 1000000.0;
		for (int i = 1; i <=M; i++)
		{
			int nowgasid = N + i;
			int nowmin = Dijkstra(nowgasid, N, N + M);
			cout << "Dijkstra Done!"< mindis)
			{
				gasid = nowgasid;
				mindis = nowmin;
				minavg = avgdis;
			}
			else if (nowmin == mindis&&avgdis < minavg)
			{
				gasid = nowgasid;
			}
		}
		if (gasid == -1)
			printf("No Solution\n");
		else printf("G%d\n%d %.1f\n", gasid-N,mindis,minavg);
	}
	system("pause");
	return 0;
}

/*
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

Output1:
G1
2 3.25

Input2:
2 1 2 10
1 G1 9
2 G1 20
Output2:
No Solution

*/

 

你可能感兴趣的:(机试准备)