PAT-1030 Travel Plan (30)

本文介绍了一种改进的Dijkstra算法实现,该算法能在找到两个节点间最短路径的同时,确保路径的成本开销也是最小的。通过具体的C++代码示例,详细展示了如何在保证最短路径的前提下选择成本最低的路径。

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

题目大意:在确保最短路径下输出费用最小的路径、最短路径数值和花费。

解题思路:和 1003.Emergency 一样的解法,改进下 Dijkstra 算法即可。

题目链接:https://www.patest.cn/contests/pat-a-practise/1030

#include <iostream>                
#include <algorithm>                
#include <set>                
#include <map>                
#include <vector>                
#include <stack>                
#include <queue>                
#include <cmath>     
#include <cstring>             
using namespace std;
const int MAXSIZE = 505;
const int INF = 1<<30;

typedef struct GMap{
	int cost,dis;
}GMap;

GMap gMap[MAXSIZE][MAXSIZE];
bool visited[MAXSIZE];
int lowcost[MAXSIZE];
int costMin[MAXSIZE];
int path[MAXSIZE];
int n,m,s,d;

void init()
{
	fill(visited,visited+MAXSIZE,false);
	fill(lowcost,lowcost+MAXSIZE,INF);
	fill(costMin,costMin+MAXSIZE,INF);
	fill(path,path+MAXSIZE,-1);
	for(int i=0;i<MAXSIZE;++i)
		for(int j=0;j<MAXSIZE;++j)
		{
			gMap[i][j].cost = INF;
			gMap[i][j].dis = INF; 
		}
}

void Dijk(int s)
{
	int u;
	visited[s] = true;
	u = s;
	path[u] = -1;
	for(int i=0;i<n;++i)
	{
		if(gMap[u][i].dis != INF)
		{
			lowcost[i] = gMap[u][i].dis;
			costMin[i] = gMap[u][i].cost;
			path[i] = u;
		}
	}
	for(int i=0;i<n-1;++i)
	{
		int Min = INF,pos;
		for(int j=0;j<n;++j)
		{
			if(lowcost[j]<Min && visited[j]==false)
			{
				Min = lowcost[j];
				pos = j;
			}
		}
		u = pos;
		visited[u] = true;
		for(int j=0;j<n;++j)
		{
			if(visited[j]==false && lowcost[u]+gMap[u][j].dis<lowcost[j])
			{
				lowcost[j] = lowcost[u]+gMap[u][j].dis;
				if(lowcost[j] == 1)
					cout << lowcost[u] <<" " << gMap[u][j].dis <<endl;
				path[j] = u;
				costMin[j] = costMin[u]+gMap[u][j].cost;
			}
			//改进的地方 
			else if(visited[j]==false && lowcost[u]+gMap[u][j].dis==lowcost[j])
			{
				if(costMin[j] > costMin[u]+gMap[u][j].cost)
				{
					path[j] = u;
					costMin[j] = costMin[u]+gMap[u][j].cost;
				}
			}
		}
	}
}

void printPath(int d)
{
	if(path[d] == -1)
	{
		cout << d << " ";
		return;
	}
	printPath(path[d]);
	cout << d <<" "; 
}

int main(int argc, char** argv) {
	cin >> n >> m >> s >> d;
	init();
	for(int i=0;i<m;++i)
	{
		int c1,c2,dis,cost;
		cin >> c1 >> c2 >> dis >> cost;
		gMap[c1][c2].dis = dis;
		gMap[c2][c1].cost = cost;
		gMap[c2][c1].dis = dis;
		gMap[c1][c2].cost = cost;
	}
	Dijk(s);
	printPath(d);
//
//	for(int i=0;i<n;++i)
//		cout<< path[i] <<endl;
//	cout<<endl;
	cout<< lowcost[d] << " " << costMin[d] << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值