1072 Gas Station

本文深入探讨了Dijkstra算法的实现细节,通过一个具体的C++代码示例,讲解了如何利用该算法解决复杂的图论问题,包括节点间的最短路径计算及在特定条件下的最优路径选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哇,菜到不行很久才完全正确,

#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1100;
const int maxm=11;
const int maxk=10010;
const int INF=0x3fffffff;
struct Node{
	int v,dis;
}temp;
int n,m,k,dmax;//n个点m条边k条路d最大服务范围 ,从1开始 
int d[maxn];//从起点到各点的最小距离 
vector<Node> G[maxk];
bool vis[maxn];//是否访问过,最短路径条数 
int toHao(string s){
	int d=0;
	bool flag=false;
	if(*s.begin()=='G'){
		flag=true;
		s.erase(s.begin());
	}while(s.size()){
		d=d*10+*s.begin()-'0';
		s.erase(s.begin());
	}if(flag) d+=n;
	return d;
}
void Dijkstra(int st){
	fill(d,d+maxn,INF);
	memset(vis,0,sizeof(vis));
	d[st]=0;
	for(int i=0;i<(n+m);i++){
		int u=-1,min=INF;
		for(int j=1;j<=n+m;j++){
			if(!vis[j]&&d[j]<min){
				u=j;
				min=d[j];
			}
		}
		if(u==-1) return;
		vis[u]=true;
		for(int j=0;j<G[u].size();j++){
			int v=G[u][j].v;
			if(!vis[v]&&d[u]+G[u][j].dis<d[v]){
				d[v]=d[u]+G[u][j].dis;
			} 
		} 
	}
}
int main(){
	cin>>n>>m>>k>>dmax;
	while(k--){
		int d1,d2,dis;
		string s1,s2;
		cin>>s1>>s2>>dis;
		d1=toHao(s1);
		d2=toHao(s2);
		temp.dis=dis;
		temp.v=d2;
		G[d1].push_back(temp);
		temp.v=d1;
		G[d2].push_back(temp); 
	}
	double maxMinDis=-1,maxSum;
	int best;
	for(int i=n+1;i<=(n+m);i++){
		Dijkstra(i);//这时d中存放此点到其他点的最小距离 
		int sum=0,flag=1,min=INF;
		for(int j=1;j<=n;j++){
			if(d[j]>dmax){
				flag=0;break;//超过最大距离 
			}else sum+=d[j];
			if(min>d[j]) min=d[j];//最小距离 
		}
		if(!flag) continue;
		if(maxMinDis<min){
			maxMinDis=min;
			best=i;
			maxSum=sum;
		}else if(maxMinDis==min&&maxSum>sum){
			best=i;
			maxSum=sum;
		}
	}//要找最大的最小距离并且没有超过最大距离,最小距离相同找最大总和的
    if(maxMinDis==-1) printf("No Solution\n");
	else printf("G%d\n%.1f %.1f",best-n,maxMinDis,round(maxSum*10/n)/10);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值