最短路径算法————迪杰斯特拉算法

该算法解决的是图中从单个源点到其他顶点的最短路径问题:

                                                                       


          

如图,寻找点1到其他顶点的最短路径。

算法思路:

        1、先找到距离源点1最近的顶点k(这个距离不一定是直线距离),可推理此时 k点已经找到最短路径。将k并入集合S。

        2、当有k并入S后,源点1到各个顶点的最短距离可能发生变化,此时需要更新这些最短距离信息。

        3、重复1、2步每次并入一个顶点。


所需的集合:

      1、 需要图G,用邻接矩阵表示。

      2、需要最短路径表D[n];

      3、需要集合final[n],用以表示点是否在集合S内。



代码实现:

#include<iostream>
using namespace std;
#define INFINITY 2147483647


//无向图的表示
class Graph
{
public:
	int vexnum;
	int** Arcs;
};

//集合final和集合D
bool final[10010];
int D[10010];

//初始化工作
void Init(Graph &MyGraph,int n)
{
	//为图动态分配内存
	MyGraph.Arcs = new int*[n+1];
	for (int i = 0; i <= n; i++)
	{
		MyGraph.Arcs[i] = new int[n + 1];
	}

	//将所有的边都初始化为无穷大,并将所有点都排除到集合S外
	for (int i = 0; i <= n; i++)
	{
		for (int j = 0; j <= n; j++)
		{
			MyGraph.Arcs[i][j] = INFINITY;
		}
		final[i] = false;
	}
}


int main()
{
	int n, m;
	cin >> n >> m;

	Graph MyGraph;
	Init(MyGraph, n);
	MyGraph.vexnum = n;

	//录入边的信息
	int a , b;
	for (int i = 0; i < m; i++)
	{
		cin >> a >> b;
		cin >> MyGraph.Arcs[a][b];
		MyGraph.Arcs[b][a] = MyGraph.Arcs[a][b];
	}
	

	//用图G初始化D表,并将源点并入S
	D[1] = 0;
	final[1] = true;	
	for (int i = 2; i <= n; i++)
	{
		D[i] = MyGraph.Arcs[1][i];
	}


	//每次找到距离源点最近的点并入S,一共有vexnum-1个点需要并
	for (int i = 0; i < MyGraph.vexnum-1; i++)
	{
		//找到S集合外距离源点最近的点,并入S
		int min = INFINITY;
		int v;
		for (int j = 1; j <= MyGraph.vexnum; j++)
		{
			if (!final[j])
			{
				if (D[j] < min)
				{
					v = j;
					min = D[j];
				}
			}
		}
		final[v] = true;

		//更新D表的信息,如果 D[v] + MyGraph.Arcs[v][j] < D[j]
		//(其中v为新并入的顶点,j为S集合外的点),则更新D[j]
		for (int j = 1; j <= MyGraph.vexnum; j++)
		{
			if (!final[j])
			{
				if (D[v] + MyGraph.Arcs[v][j] < D[j])
				{
					D[j] = D[v] + MyGraph.Arcs[v][j];
				}
			}
		}
	}


	//
	int sum = 0;
	for (int i = 1; i <= MyGraph.vexnum; i++)
	{
		sum += D[i];
	}
	cout << sum;
	system("pause");
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值