大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出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<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1015;
const int E=20010;
int n,m,k,D_s;
int h[N],e[E],en[E],dis[E];
int cnt=0;
struct res_node{
int index;
double min_dis;
double average_dis;
};
res_node res[15];
int num=0;
void add(int i,int j,int m)
{ dis[cnt]=m;
e[cnt]=j;
en[cnt]=h[i];
h[i]=cnt++;
}//关于增边的操作
bool cmp(res_node a,res_node b)
{ if(a.min_dis==b.min_dis)
{if(a.average_dis==b.average_dis)
return a.index<b.index;
else
{return a.average_dis<b.average_dis;}}
else return a.min_dis>b.min_dis;
}//最后判断顺序,结果的输出
int str_int(string a)
{
if(a[0]=='G')
{
return 1000+str_int(a.substr(1,a.size()-1));
}
else
{
int sum=0;
for(int i=0;i<a.size();i++)
{ sum*=10;
sum+=a[i]-'0';
}
return sum;
}
}//关于题目转换
void dfs(int i)
{
int vis[N];
memset(vis,0x3f,sizeof vis);
vis[i]=0;
queue<int>node;
node.push(i);
while(!node.empty())
{
int t=node.front();
node.pop();
for(int j=h[t];j!=-1;j=en[j]) {
int m = e[j];
if (vis[m] > vis[t] + dis[j])
{
vis[m] = vis[t] + dis[j];
node.push(m);
}
}//节点更新注意符号
}
int sum_dis=0;
double min_dis=0x3f;
int flag=1;
for(int i=1;i<=n;i++)
{
if (vis[i] > D_s) {
flag = 0;
break;
}
if(vis[i]<min_dis)
min_dis=vis[i];
sum_dis+=vis[i];
}
if(flag)
{
res[num].index=i;
res[num].min_dis=min_dis;
res[num].average_dis=double(sum_dis)/n;
num++;
}
return;
}//dfs
int main()
{
cin>>n>>m>>k>>D_s;
memset(h,-1,sizeof h);
for(int i=0;i<k;i++)
{
string a,b;
int c;
cin>>a>>b>>c;
int from=str_int(a);
int to=str_int(b);
add(from,to,c);
add(to,from,c);
}
for(int i=0;i<m;i++)
{
dfs(i+1+1000);
}
if(num!=0) {
sort(res, res + num, cmp);
cout << "G" << res[0].index - 1000 << endl;
printf("%.1f %.1f", res[0].min_dis, res[0].average_dis);
}
else cout<<"No Solution";
return 0;
}