迪杰斯特拉(Dijkstra)算法
迪杰斯特拉(Dijkstra)算法
迪杰斯特拉算法求得是原点到各个点之间的距离,不是任意两点间的距离,各点之间的权值不能为负,否则算法不适用
思路:数组dis:表示起点到各点的距离,maps表示各个点之间的距离,如果不相通初始化为无穷,vis表示从起点到该点的距离是否确定
将起点写入相应的数组中,dis = 0,vis = 1
然后开始找与起点相连的最短的那个点,则该店就算已经确定,确定之后就要修改相应的数据:
所有点中,只要没有没有确定距离的(vis=0)点,都需要进行判断,从起点直接到该点和经过刚才确定的点到该点,哪个更近,存储在dis中
上述循环一次只能确定一个点,所有再进行上次循环直到n-1次;
之后dis表示的就是从起点到个点的最短距离
上代码:注意初始化时,图是无向图还是有向图
#include <bits/stdc++.h> using namespace std; typedef long long ll; //重点!!!!! //写整个程序时一定要map[i][j] = map[j][i] 初始化!!!!! const int INF=0x3f3f3f3f; const int maxn=1005; int dis[maxn],maps[maxn][maxn],n;//n 点的个数 bool vis[maxn]; void Init(){ for(int i = 1;i <= n;i++){ dis[i] = INF; vis[i] = false; for(int j = 1;j <= i; j++) i == j ? maps[i][j] = 0 : maps[i][j] = maps[j][i] = INF; } } void Dijkstra(int s)//s表示起始点 { /*for(int i = 1; i <= n; i++) dis[i] = map[s][i]; vis[s] = true; 以上三行为一种Dijkstra 起始方式 另一种: (替换以上三句即可)*/ dis[s] = 0; for(int i=1;i<=n;i++) { int p=-1,minn=INF;//p记录下一个最短距离的点 for(int j=1;j<=n;j++) { if(!vis[j]&&dis[j]<minn)//j点未确定,且s->j的距离比minn小 { minn=dis[j]; p=j; } }//此时p就是已经确定的距离此时的点最短的点 vis[p]=1;//确定 for(int j=1;j<=n;j++) { if(!vis[j]) { dis[j]=min(dis[j],dis[p]+maps[p][j]); } } } } //从1开始 int main() { int m; cin>>n>>m; Init(); for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; maps[a][b] = c; } Dijkstra(1); return 0; }