最近太忙了,没什么时间来更新。当然,正如当初保证的一样,一有时间我就会更新的。
好了,言归正传
Dijkstra:
图的最短路算法之一,在边没有负权边的情况下,能解决所有的最短路问题。
原理:将点分为两个集合,集合S和集合T。并成立数组dist[],数组path[],数组S[]。
集合S:找到最短路的点
集合T:未找到最短路的点
dist[]:表示当前点到所有点的最短距离
path[]:path[i]表示当前点到点i的最短路径
S[]:S[i]表示点i是否加入了集合T
递推式:
初始:dist[i] = Edge[i][k] i 为源点
递推:u = min{dist[t]} u表示dist中最小值得序号,将其加入S集合中
dist[k] = min{dist[k],dist[k]+dist[u][k]}
要把顶点加入S中,这需要n-1次,时间复杂度为O(n^2)。
#include <iostream>
using namespace std;
#define INF 10000000
int dist[100];
int path[100];
int S[100];
int Edge[100][100];
int u,v,n;
int Dijkstra(int v0)
{
for(int i = 0;i < n;i++)
{
dist[i] = Edge[v0][i];
if(i != v0 && dist[i] < INF)
path[i] = v0;
else
path[i] = -1;
}
S[v0] = 1;
for(int i = 0;i < n;i++)
{
int min = INF,u = v0;
for(int j = 0;j < n;j++)
{
if(!S[j] && dist[j] < min)
{
u = j;
min = dist[j];
}
}
S[u] = 1;
for(int i = 0;i < n;i++)
{
if(!S[i] && Edge[u][i] < INF && dist[u] + Edge[u][i] < dist[i])
{
dist[i] = dist[u] + Edge[u][i];
path[i] = u;
}
}
}
}
int main()
{
cin >> n;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
{
cin >> Edge[i][j];
if(Edge[i][j] == 0)
Edge[i][j] = INF;
}
int i;
cin >> i;
Dijkstra(i);
return 0;
}