dijkstra 求最短路径算法

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"); }




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值