PAT A1018

本文介绍了一种使用Dijkstra算法寻找最短路径的方法,并通过深度优先搜索确定最佳路径来最小化单车调配成本的问题解决方案。

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

方法:应用dijkstra算法算出单源路径,并用pre(vector容器)记录其路径,然后利用深度遍历,计算不同路径的需要带出的单车数和带回的单车数,找到最优解并输出。

注意点:1,三个关键字优先级:路径长短,带出的单车数,带回的单车数;2,path深度遍历时,记得添加pop_back。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=520;
const int INF=10000000;
int cmax,N,sp,M;
int station[maxn];
struct edge{
	int v,time;
};
vector<edge> ver[maxn];
vector<int> pre[maxn];

bool vis[maxn]={0};
int dis[maxn];
void Dijkstra(){
	fill(dis,dis+maxn,INF);
	dis[0]=0;
	for(int i=0;i<maxn;i++){
		int min=INF,minv=-1;
		for(int j=0;j<maxn;j++){
			if(dis[j]<min&&!vis[j]){
				min=dis[j];
				minv=j;
			}
		}
		if(minv==sp||minv==-1) break;
		vis[minv]=true;
		int len=ver[minv].size();
		for(int j=0;j<len;j++){
			int tempv=ver[minv][j].v;
			if(vis[tempv]==false){
				if(dis[tempv]>dis[minv]+ver[minv][j].time){
					dis[tempv]=dis[minv]+ver[minv][j].time;
					pre[tempv].clear();
					pre[tempv].push_back(minv);
				}else if(dis[tempv]==dis[minv]+ver[minv][j].time){
					pre[tempv].push_back(minv);
				}
			}
		}//minv
	}//所有节点 
}
vector<int> temppath,fpath;
int frequire=INF,freturn=INF;
void DFS(int root){
	if(root==0){
		int lent=temppath.size(),tsum=0,trequire=0;
		for(int i=lent-1;i>=0;i--){
			if(station[temppath[i]]>=cmax/2){
				tsum+=station[temppath[i]]-cmax/2;
			}else{
				if(tsum<cmax/2-station[temppath[i]]){
					trequire+=(cmax/2-station[temppath[i]]-tsum);
					tsum=0;
				}else{
					tsum-=(cmax/2-station[temppath[i]]);
				}
			}
		}
		if(trequire<frequire){
			frequire=trequire;
			fpath=temppath;
			freturn=tsum;
		}else if(trequire==frequire&&tsum<freturn){
			fpath=temppath;
			freturn=tsum;
		}
		return;    //此句别忘了写 
	}
	temppath.push_back(root);
	int len=pre[root].size();
	for(int j=0;j<len;j++){
		DFS(pre[root][j]);
	}
	temppath.pop_back();   //此句别忘了写 
}
int main(){
	scanf("%d%d%d%d",&cmax,&N,&sp,&M);
	for(int i=1;i<=N;i++){
		scanf("%d",&station[i]);
	}
	for(int i=0;i<M;i++){
		int v1,v2;
		edge temp;
		scanf("%d%d%d",&v1,&v2,&temp.time);
		temp.v=v2;
		ver[v1].push_back(temp);
		temp.v=v1;
		ver[v2].push_back(temp);
	}
	Dijkstra();
	DFS(sp);
	printf("%d 0",frequire);
	int lenf=fpath.size();
	for(int i=lenf-1;i>=0;i--){
		printf("->%d",fpath[i]);
	}
	printf(" %d",freturn);
	return 0;
}	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值