大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出4个正整数:N(≤103)是居民点的个数;M(≤10)是垃圾箱候选地点的个数;K(≤104)是居民点和垃圾箱候选地点之间的道路的条数;DS是居民点与垃圾箱之间不能超过的最大距离。所有的居民点从1到N编号,所有的垃圾箱候选地点从G1到GM编号。
随后K行,每行按下列格式描述一条道路:
P1 P2 Dist
其中P1和P2是道路两端点的编号,端点可以是居民点,也可以是垃圾箱候选点。Dist是道路的长度,是一个正整数。
输出格式:
首先在第一行输出最佳候选地点的编号。然后在第二行输出该地点到所有居民点的最小距离和平均距离。数字间以空格分隔,保留小数点后1位。如果解不存在,则输出No Solution。
输入样例1:
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
输出样例1:
G1
2.0 3.3
输入样例2:
2 1 2 10
1 G1 9
2 G1 20
输出样例2:
No Solution
思路:对每个垃圾点进行单源最短路径,找出最短的路径,然后所有最短路径中最大的那个所在的垃圾点就是最后选择的垃圾点。
程序:
#include <cstdio>
#include <map>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
#define N 1005
#define M 10
#define INF 9999999
int n,m,k,d;
int dist[N+M];
int edge[N+M][M+N];
int vis[M+N];
void dijsktra(int s)
{
fill(vis,vis+M+N,0);
fill(dist,dist+M+N,INF);
dist[s] = 0;
for(int i = 1; i <= n + m; i++)
{
int u = -1;
int min = INF;
for(int j = 1; j <= n+m; j++)
{
if(!vis[j] && dist[j] < min)
{
min = dist[j];
u = j;
}
}
if(u == -1)
return;
vis[u] = 1;
for(int j = 1; j <= n+m; j++)
{
if(!vis[j] && dist[j] > dist[u] + edge[u][j])
dist[j] = dist[u] + edge[u][j];
}
}
}
int change(char a[])
{
string s = a;
int id = 0;
for(int i = 0; i < s.size(); i++)
{
if(s[i] == 'G')
continue;
id = id * 10 + (int)(s[i] - '0');
}
if(s[0] == 'G')
id = n + id;
return id;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&d);
fill(edge[0],edge[0]+(M+N)*(M+N),INF);
map<int,string> mp;
for(int i = 0; i < k; i++)
{
char a[10],b[10];
int dst;
scanf("%s %s %d",a,b,&dst);
int s = change(a);
int e = change(b);
if(a[0] == 'G')
mp[s] = a;
if(b[0] == 'G')
mp[e] = b;
edge[s][e] = edge[e][s] = dst;
}
int totMax = -1;
int index = -1;
int tSum = INF;
for(int i = n + 1; i <= m+n; i++)
{
dijsktra(i);
int tmin = INF;
bool flag = true;
int sum = 0;
for(int j = 1; j <= n; j++)
{
if(dist[j] > d)
{
flag = false;
break;
}
if(dist[j] < tmin)
{
tmin = dist[j];
}
sum += dist[j];
}
if(flag)
{
if(totMax < tmin)
{
totMax = tmin;
index = i;
tSum = sum;
}
else if(totMax == tmin)
{
if(sum < tSum)
{
tSum = sum;
index = i;
}
}
}
}
if(index != -1)
{
printf("%s\n",mp[index].c_str());
printf("%.1f %.1f\n",totMax*1.0,tSum*1.0/n);
}
else
printf("No Solution\n");
return 0;
}
531

被折叠的 条评论
为什么被折叠?



