L3-005 垃圾箱分布 (30 分)
大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
#includeusing namespace std;const int maxn=1020;const int inf=32787;int n,m,o,p,l;//居民点、垃圾桶、路径、最大距离、l=居民点数+垃圾桶数 int T[maxn][maxn];//存无向图 int D[maxn];//存单个垃圾桶到每一个居民点的最短距离 bool flag[maxn];//dijkstra辅助标记数组 void Djs(int a){for(int i=1;i<=l;i++){D[i]=T[a][i];}flag[a]=true;D[a]=0;for(int i=1;i<=l;i++){int minid=-1,Min=inf;for(int j=1;j<=l;j++){if(!flag[j]&&Min>D[j]){Min=D[j];minid=j;}}if(minid==-1) return ;flag[minid]=true;for(int j=1;j<=l;j++){if(!flag[j]&&D[j]>D[minid]+T[minid][j]){D[j]=D[minid]+T[minid][j];}}}}int main(void){cin>>n>>m>>o>>p;l=n+m;for(int i=1;i<=l;i++)//初始化 {for(int j=1;j<=l;j++){T[i][j]=inf;}}//用数组存储居民点和垃圾桶1-n为居民点下标、n+1~l为垃圾桶下标 //区分输入是居民点还是垃圾桶 for(int i=0;i>s1>>s2>>w;if(s1[0]=='G'){s1.erase(0,1);a=stoi(s1)+n;}else a=stoi(s1);if(s2[0]=='G'){s2.erase(0,1);b=stoi(s2)+n;}else b=stoi(s2);T[a][b]=T[b][a]=w;}//id:符合条件的垃圾桶序号 sum:最短距离总和 min_max:所有最短距离中的最小值 int id=0,sum=0,min_min=0; double aver=0;//平均值 for(int i=n+1;i<=l;i++){memset(D,0,sizeof(D)); memset(flag,0,sizeof(flag)); Djs(i);int min_1=inf,max_1=0;int sum_1=0;double aver_1=0;for(int j=1;j<=n;j++){if(D[j]max_1) max_1=D[j];//找最大值 sum_1+=D[j];}if(max_1>p) continue;//最大值若超出题目规定的最大限额 aver_1=sum_1/(n*1.0);if(min_1>min_min)//求最短距离里最长的地方 {min_min=min_1;id=i-n;aver=aver_1;}else if(min_1==min_min)//若相等,再求平均距离最短的地方 {if(aver>aver_1){aver=aver_1;id=i-n;}}//垃圾桶从小到大遍历,故编号就不用再进行比较 }if(id==0) cout<<"No Solution"<