Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
其基本思想是,设置顶点集合visit并不断地作贪心选择来扩充这个集合。一个顶点属于集合visit当且仅当从源到该顶点的最短路径长度已知。
初始时,visit中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过visit中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-visit中取出具有最短特殊路长度的顶点u,将u添加到visit中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
dijkstra 模板 :
//dijkstra 模板
#include<iostream>
#include<string.h>
#include<algorithm>
#define N 1005
#define M 999999
#define CLR(array,val) memset(array,val,sizeof(array))
#define FOR(i,s,t) for(int i=(s);i<=(t);i++)
using namespace std;
int dist[N];//记录当前点到源点的距离
int prev[N];//记录当前点的前一个结点
int map[N][N];//记录两点间的路径长度
int n,line;//结点总数和路径数
void Dijkstra(int n,int v,int *dist,int *prev,int map[N][N])
{ bool visit[N];//记录结点是否已存入visit集合中
FOR(i,1,n)
{ dist[i]=map[v][i];
visit[i]=true;
if(dist[i]==M) prev[i]=0;
else prev[i]=v;//初始化当前结点前一个结点为源节点。
}
dist[v]=0;
visit[v]=false;//v结点已存入visit集合中
FOR(i,1,n)
{ int minx=M;
int u=v;//u保存的是当前邻接点中离源点最短的。
FOR(j,1,n)
if(visit[j]&&dist[j]<minx)
{ u=j;
minx=dist[j];
}
visit[u]=false;
FOR(j,1,n)
if(visit[j]&&dist[u]+map[u][j]<dist[j])
{ dist[j]=dist[u]+map[u][j];
prev[j]=u;
}
}
}
void Searchpath(int *prev,int v,int u )
{ int tot=1;
int que[N];
que[tot++]=u;
int temp=prev[u];
while(temp!=v)
{ que[tot++]=temp;
temp=prev[temp];
}
que[tot]=v;
for(int i=tot;i>=1;--i)
if(i!=1) cout<<que[i]<<"->";
else cout<<que[i]<<endl;
}
int main()
{
cin>>n>>line;
CLR(dist,M);
CLR(map,M);
FOR(i,1,line)
{ int a,b,c;
cin>>a>>b>>c;
if(c<map[a][b])
map[a][b]=map[b][a]=c;
}
Dijkstra(n,1,dist,prev,map) ;
cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;
cout << "源点到最后一个顶点的路径为: ";
Searchpath(prev, 1, n);
system("pause");
}