PTA:7-125 垃圾箱分布 (30分)(dijkstra--加解析)有一个测试点没过,欢迎讨论

半世苍凉 提交于 2020-01-31 01:59:55

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;
}

在这里插入图片描述
欢迎大家批评改正!!!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!