L3-005. 垃圾箱分布
时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出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 <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define LL long long
#define lt x<<1
#define rt x<<1|1
const int maxn = 1e5+111;
const int inf = 0x3f3f3f3f;
int mp[1020][1020];
int dis[1020];
int n,m,k,ds;
int f(char s[])
{
int len = (int)strlen(s);
if(s[0]=='G'){
int sum=0;
for(int i=1;i<len;i++)
sum=sum*10+s[i]-'0';
return sum+n;
}else{
int sum=0;
for(int i=0;i<len;i++)
sum=sum*10+s[i]-'0';
return sum;
}
}
int ans_flag=0;
int ans_Max=0;
int ans_sum;
void dij(int s)
{
int vis[maxn];
int nn=n+m;
for(int i=1;i<=nn;i++) dis[i]=inf,vis[i]=0;
dis[s]=0;
for(int i=1;i<=nn;i++){
int k=0;
int Min=inf;
for(int j=1;j<=nn;j++){
if(!vis[j]&&Min>dis[j]){
k=j;
Min=dis[j];
}
}
if(!k) break;
vis[k]=1;
for(int j=1;j<=nn;j++){
if(dis[j]>dis[k]+mp[k][j]){
dis[j]=dis[k]+mp[k][j];
}
}
}
int Min=inf;
int sum=0;
for(int i=1;i<=n;i++){
if(dis[i]>ds)
return;
Min=min(Min,dis[i]);
sum+=dis[i];
}
if(ans_Max<Min){
ans_Max=Min;
ans_flag=s-n;
ans_sum=sum;
}else if(ans_Max==Min){
if(ans_sum>sum){
ans_sum=sum;
ans_flag=s-n;
}else if(ans_sum==sum){
ans_flag=min(ans_flag,s-n);
}
}
}
int main()
{
memset(mp,inf,sizeof mp);
scanf("%d %d %d %d",&n,&m,&k,&ds);
for(int i=1;i<=k;i++){
char s1[5],s2[5];
scanf("%s %s",s1,s2);
int u=f(s1);
int v=f(s2);
int w;scanf("%d",&w);
if(w<mp[u][v])
mp[u][v]=mp[v][u]=w;
}
for(int i=1;i<=m;i++){
dij(n+i);
}
if(ans_flag==0){
printf("No Solution\n");
}else{
printf("G%d\n",ans_flag);
printf("%0.1lf %0.1lf\n",1.0*ans_Max,1.0*ans_sum/n+1e-8);
}
return 0;
}