Dijkstra算法实现类—邻接矩阵,一般实现

(在后面更新了Dijkstra算法的实现,用邻接表+优先队列实现。链接如下:http://blog.csdn.net/betabin/article/details/7390403

有向权图关于单源最短路径算法,Dijkstra算法。

算法可以形象理解为小城镇(最开始就是起点)的扩张,最后把世界吃掉。每次挑选一个离小城镇最近的地点,然后吃掉,更新各个未吃掉的地点到小城镇的距离。刷新距离主要是比较到刚刚吃掉的地点的距离和之前的最短距离。详细的也不多讲,贴出代码。简单易懂,图就用简单的矩阵表示,时间复杂度O(V2)。(V表示点数。)

#include <iostream>
#include <set>

using namespace std;

#define GRAPHSIZE 100
#define NOSET_INT -1
#define ERROR_POSITIVE_NUM -1
#define INFINITE 2147483647

class Graph
{
public:
	int weight[GRAPHSIZE][GRAPHSIZE];
	int source;
	int destination;

	Graph();//Initialize all variables.
	int getShortByDijkstra();//Get the shortest weight by Dijkstra.

private:
	set<int> sourceSet;
	set<int> destinationSet;

	int getNextShortPoint(int shortvalue[]);//Find next shortest point in destination set.
	void refreshShortest(int nextshortpoint, int shortvalue[]);//Refresh the array of shortvalue.
};

Graph::Graph()
{
	source = NOSET_INT;
	destination = NOSET_INT;
	
	for (int i = 0; i < GRAPHSIZE; i++)
	{
		for (int j = 0; j < GRAPHSIZE; j++)
		{
			weight[i][j] = INFINITE;
		}

		destinationSet.insert(i);
	}
}

int Graph::getShortByDijkstra()
{
	if ( NOSET_INT == source || NOSET_INT == destination)
	{
		return ERROR_POSITIVE_NUM;
	}
	else if (source == destination)
	{
		return 0;
	}

	sourceSet.insert(source);
	destinationSet.erase(source);

	int shortest[GRAPHSIZE];
	for (int i = 0; i < GRAPHSIZE; i++)
	{
		shortest[i] = weight[source][i];
	}
	shortest[source] = 0;

	int shortestPoint;
	for (int j = 1; j < GRAPHSIZE; j++)
	{
		shortestPoint = getNextShortPoint(shortest);
		if (INFINITE == shortest[shortestPoint])
		{
			return INFINITE;
		}
		else if (shortestPoint == destination)
		{
			return shortest[shortestPoint];
		}

		sourceSet.insert(shortestPoint);
		destinationSet.erase(shortestPoint);

		refreshShortest(shortestPoint, shortest);
	}

	return ERROR_POSITIVE_NUM;
}

int Graph::getNextShortPoint(int shortvalue[])
{
	set<int>::iterator scanner = destinationSet.begin();
	int shortestpoint = *scanner;
	
	while (scanner != destinationSet.end())
	{
		if (shortvalue[shortestpoint] > shortvalue[*scanner])
		{
			shortestpoint = *scanner;
		}

		scanner++;
	}

	return shortestpoint;
}

void Graph::refreshShortest(int nextshortpoint, int shortvalue[])
{
	set<int>::iterator scanner = destinationSet.begin();
	while (scanner != destinationSet.end())
	{
		unsigned int a = shortvalue[*scanner];
		unsigned int b = (unsigned int)shortvalue[nextshortpoint] + (unsigned int)weight[nextshortpoint][*scanner];
		if (a > b)
		{
			shortvalue[*scanner] = shortvalue[nextshortpoint] + weight[nextshortpoint][*scanner];
		}
		scanner++;
	}
}

int main()
{
	Graph school;
	
	int n;
	int s, d, w;

	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> s >> d >> w;
		school.weight[s][d] = w;
	}

	cin >> school.source >> school.destination;

	cout << school.getShortByDijkstra() << endl;

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值