1030 Travel Plan (30分) PAT之图最短路径算法之迪杰斯克拉算法

题目

A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format
详细题目看原链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392
题目大意就是给出一个无向图,边权有两种,一种是距离,另一种是金钱,现要求给出起点和终点,输出最短路径、最短距离和最少花费。

分析

采用迪杰斯克拉算法解题,创建d【】和c【】记录最短距离和最少花费。
创建pre【】记录路径。
直接上代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxv = 510;
const int INF = 0x3fffffff;

int n, m, st, ed, G[maxv][maxv], cost[maxv][maxv];
int d[maxv], c[maxv], pre[maxv];
bool vis[maxv] = {false};

void dijsk(int s)
{
	fill(d, d+maxv, INF);
	fill(c, c+maxv, INF);
	for(int i = 0; i < n; i++) pre[i] = i;
	d[s] = 0;
	c[s] = 0;
	for(int i = 0; i < n; i++)
	{
		int u = -1, MIN = INF;
		for(int j = 0; j < n; j++)
		{
			if(vis[j] == false && d[j] < MIN)
			{
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++)
		{
			if(vis[v] == false && G[u][v] != INF)
			{
				if(d[u] + G[u][v] < d[v])
				{
					d[v] = d[u] + G[u][v];
					c[v] = c[u] + cost[u][v];
					pre[v] = u;
				}
				else if(d[u] + G[u][v] == d[v])
				{
					if(c[u] + cost[u][v] < c[v])
					{
						c[v] = c[u] + cost[u][v];
						pre[v] = u;
					}
					
				}
			}
		}
	}
 }

void dfs(int s)
{
	if(s == st)
	{
		printf("%d ", s);
		return;
	}
	dfs(pre[s]);
	printf("%d ", s);
 } 

int main()
{
	scanf("%d%d%d%d", &n, &m, &st, &ed);
	int u, v;
	fill(G[0], G[0] + maxv*maxv, INF);
	for(int i = 0; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		scanf("%d%d", &G[u][v], &cost[u][v]);
		G[v][u] = G[u][v];
		cost[v][u] = cost[u][v];
	}
	dijsk(st);
	dfs(ed);
	printf("%d %d", d[ed], c[ed]);
	return 0;
}

收获

1.这是一类套模板的题,只要你模板熟悉,往上套就完事。
2.这类题一般是除了求最短路径外还参合着第二标尺如点权,新增边权,最短路径的条数等等,这些新增的元素只需要再更新d【】的时候同时更新即可解决。
3.为了方便记忆,迪杰斯克拉算法可归纳成三步走:一初始化(图和其他),二找最小d【】,三找中间变量v,收工。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值