Dijsktra 最短路径和堆算法

下面是使用矩阵存储图信息,然后使用堆搜索下一个最短路径点的算法,其中堆的实现使用priority_queue容器:

这里只是提高了选择下一个最短路径点的时间效率,这里的最终效率没有提高;相对实现简单,但是并不完善,如大数据的时候有可能挤爆堆。

可以使用邻接矩阵,就能把时间效率提高到O(ElgV),如我另一篇博客:

http://blog.csdn.net/kenden23/article/details/27523185


#include <stdio.h>
#include <algorithm>
#include <queue>
using std::queue;

class Dijsktra_4
{
	const static int Vs = 9;
	const static int MAX_INT = -((1<<31)+1);

	struct VecVal
	{
		int vec, val;
		explicit VecVal(int e = 0, int a = 0) : vec(e), val(a) {}
		bool operator<(const VecVal &ve) const
		{
			return ve.val < val;
		}
	};

	int getMinIndex(priority_queue<VecVal> &pqv, bool selected[])
	{
		int minI = -1;
		while (pqv.size() && selected[pqv.top().vec])
			pqv.pop();
		if (pqv.size()) minI = pqv.top().vec, pqv.pop();
		return minI;
	}

	void getShortestPath(int gra[Vs][Vs], int pathVal[], int src)
	{
		bool selected[Vs];
		for (int i = 0; i < Vs; i++)
		{
			pathVal[i] = MAX_INT;
			selected[i] = false;
		}
		priority_queue<VecVal> pqv;
		pathVal[src] = 0;
		VecVal ve(src, 0);
		pqv.push(ve);

		for (int i = 0; i < Vs-1; i++)
		{
			int u = getMinIndex(pqv, selected);
			if (-1 == u) break;
			selected[u] = true;
			for (int v = 0; v < Vs; v++)
			{
				if (!selected[v] && gra[u][v] && 
					gra[u][v] + pathVal[u] < pathVal[v])
				{
					pathVal[v] = gra[u][v] + pathVal[u];
					pqv.push(VecVal(v, pathVal[v]));
				}
			}
		}		
	}
public:
	Dijsktra_4(int src = 0)
	{
		int gra[Vs][Vs] = {
			{0, 4, 0, 0, 0, 0, 0, 8, 0},
			{4, 0, 8, 0, 0, 0, 0, 11, 0},
			{0, 8, 0, 7, 0, 4, 0, 0, 2},
			{0, 0, 7, 0, 9, 14, 0, 0, 0},
			{0, 0, 0, 9, 0, 10, 0, 0, 0},
			{0, 0, 4, 0, 10, 0, 2, 0, 0},
			{0, 0, 0, 14, 0, 2, 0, 1, 6},
			{8, 11, 0, 0, 0, 0, 1, 0, 7},
			{0, 0, 2, 0, 0, 0, 6, 7, 0}
		};

		int shortestPathVal[Vs];
		getShortestPath(gra, shortestPathVal, src);

		printf(" V%d's Shortest paths is :\n", src);
		for (int i = 0; i < Vs; i++)
		{
			printf(" -> V%d : %d\n", i, shortestPathVal[i]);
		}
	}
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值