PAT.A1030 Travel Plan

返回目录在这里插入图片描述

题意

有N个城市(编号为0~N-1)、M条道路(无向边),并给出M条道路的距离属性与花费属性。 现在给定起点S与终点D,求从起点到终点的最短路径、最短距离及花费。注意:如果有多条最短路径,则选择花费最小的那条。

样例(可复制)

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
//output
0 2 3 3 40

注意点

  1. 本题使用Dijkstra。
  2. 注意使用fill附初值,memset只常用于赋值0,-1,false。
#include <bits/stdc++.h>
using namespace std;

int n,m,st,ed;//城市,边,起点,终点
int D[510][510],F[510][510];//D存放距离,F存放费用
int dis[510];//存放从st出发的距离 
bool vis[510]={false};//标记是否访问过
int pre[510],fee[510];//最优前驱,费用 
vector<int> path;//存放最优路径
void Dijkstra(){
	fill(dis,dis+n,INT_MAX);
	fill(fee,fee+n,INT_MAX);
	dis[st]=0;
	fee[st]=0;
	while(!vis[ed]){
		int minn=INT_MAX,v;
		for(int i=0;i<n;i++){
			if(!vis[i]&&dis[i]<minn){
				minn=dis[i];
				v=i;
			}
		}
		vis[v]=true;
		for(int i=0;i<n;i++){
			if(!vis[i]&&D[v][i]!=0&&dis[i]>dis[v]+D[v][i]){
				pre[i]=v;
				fee[i]=fee[v]+F[v][i];
				dis[i]=dis[v]+D[v][i];
			}else if(D[v][i]!=0&&dis[i]==dis[v]+D[v][i]&&fee[i]>fee[v]+F[v][i]){
				pre[i]=v;
				fee[i]=fee[v]+F[v][i];
			}
		}
	}
}
void DFS(int v){
	path.push_back(v);
	if(v==st)return;
	DFS(pre[v]);
}
int main(){
	cin>>n>>m>>st>>ed;
	int u,v,d,f;
	while(m--){
		scanf("%d%d%d%d",&u,&v,&d,&f);
		D[u][v]=D[v][u]=d;
		F[u][v]=F[v][u]=f;
	}
	Dijkstra();
	DFS(ed);
	for(int i=path.size()-1;i>=0;i--)printf("%d ",path[i]);
	printf("%d %d",dis[ed],fee[ed]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽会微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值