Dijkstra算法
_ ** 时隔多月,我又回来了!**_
今天下午久违的又学了会儿算法,又重新学习了一遍Dijkstra,这是第三次重新学习Dijkstra(*以前学的都忘完了>_<*).
废话先不bb,上代码。
#include<bits/stdc++.h> using namespace std; #define INF 9999999 #define M 1000 int d[M]; int p[M]={0}; int con[M][M]; int n,line; //n点数,边数line struct node{ char name; }w[M]; void Dijkstra(int v,int *d,int p[],int con[M][M]) //初始点v { int vis[M]; for(int i=1;i<=n;i++) //第一步,确定与初始点v连接的点的路径 { d[i]=con[v][i]; vis[i]=0; //vis初始化 if(d[i]!=INF) p[i]=v; } d[v]=0; //对第一个点初始化 vis[v]=1; for(int i=1;i<=n;i++) //第二布,两重循环 ,每次循环又分两步 。判断所有点 { int a=INF,id=v; for(int j=1;j<=n;j++) //1、找出该次循环中距离最小的点, 该点可能是一条新的路径 { if(d[j]<a && !vis[j]) { a=d[j]; //a确定值 id=j; //id确定点的下标 } } vis[id]=1; //已判断过 ,已经走过 for(int j=1;j<=n;j++) //2、 从此时距离最短的点出发,更新与id相连的点的值,有两种情况 { if(!vis[j] && con[id][j]<INF) { int newdis=d[id]+con[id][j]; if(newdis<d[j]) //根据 newdis与d[j]判断 { d[j]=newdis; p[j]=id; } } } } } int idex(char a) { for(int i=1;i<M;i++) if(w[i].name==a) return i; } void fun(int *p,char fist,char last) { char x[M]; int f=idex(fist),l=idex(last); cout<<"从"<<fist<<"到"<<last<<"的最短路径为:\n"; x[0]=last; int y=1; int t=p[l]; while(t!=f) { x[y++]=w[t].name; t=p[t]; } cout<<fist; for(int i=y-1;i>=0;i--) cout<<"->"<<x[i]; cout<<"\n"; } int main() { char a,b; int dis; cout << "************算法6.10 迪杰斯特拉算法**************\n"; cout<<"请输入总点数,总边数:"; cin>>n>>line; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) con[i][j]=INF; for(int i=1;i<=n;i++) { cout<<"请输入第"<<i<<"个点:"; cin>>w[i].name; } for(int i=1;i<=line;i++) { cout<<"请输入第"<<i<<"条边:"; cin>>a>>b>>dis; int a1=idex(a),b1=idex(b); if(dis<INF) { con[a1][b1]=dis; con[b1][a1]=dis; } } cout << "*****无向网G创建完成!*****\n" ; for(int i=1;i<=n;i++) d[i]=INF; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(con[i][j]==INF) cout<<"∞ "; else cout<<con[i][j]<<" "; } printf("\n"); } cout<<"请输入起点和终点:"; cin>>a>>b; Dijkstra(idex(a), d, p, con); cout << a<<"到最后"<<b<<"的最短路径长度为: " << d[idex(b)] <<"\n"; fun(p,a,b); return 0; }
这次学习总结了Dijkstra算法模板函数的几个主要步骤,因为这个函数没有用到递归,只
用了两个循环,因此可以分为从上到下的两步。
Dijkstra算法模板函数主要有两步:
一、
确定与初始点v连接的点的路径 ,检查所有与初始点连接的点并更新他们的d[i]值。
二、
一个二重嵌套循环,每次for循环里又分两步:
1、
找出此次循环中(d[i]中)距离值最小的,并分别用id,a记录该点对应的下标与d[i].
2、
以这个点(id)为初始点,更新所有与该点相连通的点(d数组).
重复第二步。
**以上。**
原文地址:https://www.cnblogs.com/zjydeoneday/p/11980241.html
时间: 2024-10-14 17:52:59