7-125 垃圾箱分布 (30分)
输入样例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
思路
题目大意:求最短距离尽可能的大,而且总的距离尽可能小;相同的话再接着判断。。。
该题主要用dijkstra算法,可以计算出该垃圾桶离用户的最短距离和垃圾桶到所有用户的总距离。
具体解析见代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,dmax,nm,sum,dmin,flag=0,flag2=0,minn,cnt=0;
int d[1100],cost[1100][1100],vis[1100];
struct rubbish{
int index,mind,sumd;
}r[12];
int deal(char *s){ //对输入的数据进行处理,使得用户编号从1-n,垃圾桶编号从n+1至n+m;
if(isdigit(s[0])) return atoi(s);
else{
if(s[1]=='1'&&s[2]=='0') return n+10;
else return n+(s[1]-'0');
}
}
void dijkstra(int s){
sum=0;
dmin=1e9;
flag=0;
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
for(int i=1; i<=nm; i++) d[i]=cost[s][i];
vis[s]=1;
d[s]=0;
for(int i=1; i<=nm-1; i++){
int k=-1,minn=1e9;
//从未选取的点中找一个离起点最近的点,这里要包括垃圾桶待选点
for(int j=1; j<=nm; j++){
if(!vis[j]&&d[j]<minn){
minn=d[j];
k=j;
}
}
if(k==-1) break;
vis[k]=1;
//判断是否经过该点到其他点的距离比之前更短,进行更新(建议读者先了解dijstra算法)
for(int j=1; j<=n; j++){
if(!vis[j]&&d[j]>d[k]+cost[k][j]){
d[j]=d[k]+cost[k][j];
}
}
}
for(int i=1; i<=n; i++){
if(d[i]<dmin) dmin=d[i]; //找出最近的住户
if(d[i]>dmax) flag=1;//该位置超出最大距离
sum+=d[i];//垃圾桶到各个用户的总距离
}
return;
// cout<<"dmin: "<< dmin << " sum: "<<sum<<" ans: "<<(double)sum/n<<endl;
}
bool cmp(rubbish &x, rubbish &y){ //选出最佳垃圾桶位置
if(x.mind>y.mind||(x.mind==y.mind&&x.sumd<y.sumd)||(x.mind==y.mind&&x.sumd==y.sumd&&x.index<y.index))
return true;
return false;
}
int main(){
cin>>n>>m>>k>>dmax;
nm=n+m;
char p1[5],p2[5];
int dis;
while(k--){
int a,b;
cin>>p1>>p2>>dis;
a=deal(p1);
b=deal(p2);
cost[a][b]=dis; //保存a,b端点的距离
cost[b][a]=dis;
}
for(int i=1; i<=nm; i++){
for(int j=1; j<=nm; j++){
if(cost[i][j]==0){
cost[i][j]=1e9;
cost[j][i]=1e9;
}
}
}
for(int i=n+1; i<=nm; i++){
dijkstra(i);
if(!flag){ //符合条件的垃圾桶存入结构体中
flag2=1;
r[cnt].index=i-n;
r[cnt].mind=dmin;
r[cnt].sumd=sum;
cnt++;
}
}
if(!flag2) cout<<"No Solution"<<endl;
else{ //选出最佳垃圾桶位置
sort(r,r+cnt,cmp);
cout<<"G"<<r[0].index<<endl;
cout<<fixed<<setprecision(1)<<(double)r[0].mind<<" "<<(double)r[0].sumd/n+0.05<<endl;
}
return 0;
}
欢迎大家批评改正!!!
来源:CSDN
作者:zlzhucsdn
链接:https://blog.csdn.net/weixin_43581819/article/details/104114898