PAT (Advanced Level) Practice 1003 Dijkstra算法扩展,求最短路径数量+最大权值和

一、概述

本题属于数据结构中图的部分,中心思想是利用dijkstra算法,找到源点和目标点的最短路径数量。输出最短路径数量以及一条路径上可供调遣的最大人数。核心问题是理解dijkstra算法的应用。理论部分十分容易理解,在源点周围找到第一个距离最短的点,更新再找第二个第三个,手动模拟很方便,但是转换为代码没那么简单。第二是如何找到最短路径的条数以及最大人数,这需要在原算法的基础上改进,还是不那么简单的,至少我做了好久。

二、分析

1、准备工作

主要是录入题干数据。

采用两个函数,创造新图以及打印图。

如下:

数据结构

比一般的图多了两个元素,即源点和目标点。

typedef struct {
	VertexType vexs[Max];
	EdgeType arc[Max][Max];
	int vnum, edgenum;
	int source, desti;
}Mgraphy;

这是创造图的函数。

要注意首先将整个图的邻接矩阵初始化。然后录入数据。

void CreateGraphy(Mgraphy *G)
{
	scanf("%d", &G->vnum);
	scanf("%d", &G->edgenum);
	scanf("%d", &G->source);
	scanf("%d", &G->desti);
	int i = 0;
	for (i = 0; i < G->vnum; i++)
		scanf("%d", &G->vexs[i]);
	int j = 0;
	for (i = 0; i < G->edgenum; i++)
		for (j = 0; j < G->edgenum; j++)
			G->arc[i][j] = Infinite;
	int row, line,length;
	for (i = 0; i < G->edgenum; i++)
	{
		scanf("%d %d", &row, &line);
		scanf("%d", &length);
		G->arc[row][line] = length;
		G->arc[line][row] = length;
	}
}

这是打印图的函数。

没什么用,我只打印了邻接矩阵,在上传的时候还要注释掉,只是debug的时候方便点。

void PrintGraphy(Mgraphy *G)
{
	int i, j;
	for (i = 0; i < G->edgenum; i++)
	{
		for (j = 0; j < G->edgenum; j++)
			printf("%d    ", G->arc[i][j]);
		printf("\n");
	}
}

2、dijsktra函数

本题核心部分。该函数的最主要工作是对两个数组进行操作。其一是最短路径数组sqtable,其二是访问数组final。

前者用于记录源点到各点的最短路径,这是其最重要的特点,后者用于记录哪些点已访问,哪些点未访问。整个函数的工作流程如下:

①函数数组初始化。数组元素都置为0,注意不要用{0},pta服务器不认,报错,用memset函数。然后将源点连接的点的弧长填入sqtable,此时满足sqtable的特点。

②进入主循环,循环次数为总的节点数量。

主循环内的小循环一,用于挑选出sqtable中的最小的第k个节点,并将final中对应值置为1。这代表着从源点到第k个节点的最短路径已找到。

既然已找到一个新的最短路径节点,那么可能会出现新的节点,原有节点的距离也可能不再是最小的,其特点被破坏。这样一来,整个sqtable可能需要更新。

进入小循环二。找到满足以下条件的节点:

最短路径还未找到且由于k的存在,从源点到k加上从k到该点(w)的距离和小于从源点到w的距离。这说明出现了新的更优路径,则将该路径和代替原值填入sqtable。即:经过小循环二后,sqtable再次满足它的特点。

既然sqtable已更新,那么小循环一即可找到新的最小路径。由此直到大循环循环完毕,final的值全为1,sqtable存储所有最短路径(对于连通图来说)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值