(在后面更新了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;
}