大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出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<bits/stdc++.h>
using namespace std;
const int N=1e3+100;
const int inf=0x3f3f3f3f;
int mp[N][N];
bool vis[N];
int dis[N];
int n,m,k,ds;
void Dijkstra(int v)
{
fill(vis,vis+N,false);
fill(dis,dis+N,inf);
for(int i=1;i<=n+m;i++) dis[i]=mp[v][i];
dis[v]=0;
for(int i=0;i<n+m;i++){
int u=-1;
int minn=inf;
for(int j=1;j<=n+m;j++){
if(!vis[j]&&minn>dis[j]){
u=j;
minn=dis[j];
}
}
if(u==-1) return ;
vis[u]=true;
for(int j=1;j<=n+m;j++){
if(!vis[j]&&mp[u][j]+dis[u]<dis[j]){
dis[j]=mp[u][j]+dis[u];
}
}
}
}
struct node
{
int id;
double minn,v;
node(){}
node(int id1,double minn1,double v1):id(id1),minn(minn1),v(v1){}
friend bool operator <(node A,node B){
if(A.minn==B.minn){
if(A.v==B.v){
return A.id<B.id;
}
else return A.v<B.v;
}
else return A.minn>B.minn;
}
};
int main()
{
memset(mp,inf,sizeof(mp));
scanf("%d %d %d %d",&n,&m,&k,&ds);
set<int>st;
for(int i=0;i<k;i++){
char s1[5],s2[5];
scanf("%s %s",s1,s2);
int t1=0,t2=0;
int x;
scanf("%d",&x);
if(s1[0]=='G'){
int len =strlen(s1);
for(int j=1;j<len;j++){
t1=t1*10+s1[j]-'0';
}
t1+=n;
st.insert(t1);
}
else{
sscanf(s1,"%d",&t1);
}
if(s2[0]=='G'){
int len=strlen(s2);
for(int j=1;j<len;j++){
t2=t2*10+s2[j]-'0';
}
t2+=n;
st.insert(t2);
}
else{
sscanf(s2,"%d",&t2);
}
mp[t1][t2]=mp[t2][t1]=x;
}
vector<node>vec;
for(auto it:st){
Dijkstra(it);
bool flag=false;
int sum=0;
int minn=inf;
for(int i=1;i<=n;i++){
if(dis[i]>ds){
flag=true;
break;
}
else{
sum+=dis[i];
if(minn>dis[i]){
minn=dis[i];
}
}
}
if(!flag){
vec.push_back(node(it,minn,sum*1.0/n));
}
}
if(vec.size()==0) puts("No Solution");
else{
sort(vec.begin(),vec.end());
printf("G%d\n",vec[0].id-n);
printf("%.1f %.1f\n",vec[0].minn,vec[0].v);
}
return 0;
}