大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出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
对m个垃圾桶位置都求一次它到其他点的最短距离,还要找出所有点中最近的距离以及平均距离,如果存在一点的最短距离>ds,则该位置不能放置垃圾桶。
然后对m个位置进行排序,先按最近距离大的排,如果最近距离相同则按平均距离小的排,再相同则按编号小的排
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 2e4 + 10;
typedef long long LL;
int n,m,k,ds,x,y,z;
int u[N],ft[N],nt[N],cost[N],sz = 0;
int dis[N];
struct node2{
double ave,mi;
int id;
}trash[15];
bool cmp(node2 a,node2 b){
if(a.mi!=b.mi) return a.mi > b.mi;
if(a.ave!=b.ave) return a.ave < b.ave;
return a.id < b.id;
}
struct node{
int id,cost;
node(int a,int b){id = a; cost = b;}
bool friend operator < (node a,node b){
return a.cost > b.cost;
}
};
void dij(int st){
priority_queue<node>q;
q.push(node(st,0));
memset(dis,INF,sizeof dis);
dis[st] = 0;
while(!q.empty()){
int pos = q.top().id,ct = q.top().cost; q.pop();
if(ct>dis[pos]) continue;
for(int i=ft[pos];i;i=nt[i]){
if(dis[pos]+cost[i]<dis[u[i]]){
dis[u[i]] = dis[pos] + cost[i];
q.push(node(u[i],dis[u[i]]));
}
}
}
trash[st-n].mi = INF; trash[st-n].ave = 0;
trash[st-n].id = st-n;
for(int i=1;i<=n;i++){
trash[st-n].mi = min(trash[st-n].mi, (double)dis[i]);
trash[st-n].ave += dis[i];
if(dis[i]>ds){
trash[st-n].ave = INF;
trash[st-n].mi = 0;
break;
}
}
if(trash[st-n].ave!=INF) trash[st-n].ave /= n;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&ds);
for(int i=0;i<k;i++){
char s1[10],s2[10];
x = y = 0;
scanf("%s%s%d",s1,s2,&z);
if(s1[0]=='G') {
if(s1[2]=='0') x = n+10;
else x = n + s1[1]-'0';
}else{
for(int j=0;s1[j];j++){
x = x*10 + s1[j]-'0';
}
}
if(s2[0]=='G') {
if(s2[2]=='0') y = n+10;
else y = n + s2[1]-'0';
}else{
for(int j=0;s2[j];j++){
y = y*10 + s2[j]-'0';
}
}
u[++sz] = y; nt[sz] = ft[x]; ft[x] = sz; cost[sz] = z;
u[++sz] = x; nt[sz] = ft[y]; ft[y] = sz; cost[sz] = z;
}
for(int i=1;i<=m;i++) dij(n+i);
sort(trash+1,trash+1+m,cmp);
if(trash[1].ave==INF){
printf("No Solution\n");
}else{
printf("G%d\n",trash[1].id);
printf("%.1lf %.1lf\n",trash[1].mi,trash[1].ave);
}
return 0;
}