Dijkstra算法O (N2)
Posted ioioioioioio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dijkstra算法O (N2)相关的知识,希望对你有一定的参考价值。
用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法。也就是说,只能计算起点只有一个的情况。
Dijkstra的时间复杂度是O (N2),它不能处理存在负边权的情况。
算法描述:
设起点为s,dis[v]表示从s到v的最短路径,pre[v]为v的前驱节点,用来输出路径。
a)初始化:dis[v]=∞(v≠s); dis[s]=0; pre[s]=0;
b)For (i = 1; i <= n ; i++)
1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的。
2.u标记为已确定最短路径
3.For 与u相连的每个未确定最短路径的顶点v
if (dis[u]+w[u][v]<dis[v])
{
dis[v]=dis[u]+w[u][v];
pre[v]=u;
}
c)算法结束:dis[v]为s到v的最短距离;pre[v]为v的前驱节点,用来输出路径。
算法实现步骤:
设图G用邻接矩阵的方式存储在GA中,GA[I,j]=maxint表示vi,vj是不关联的,否则为权值(大于0的实数)。设集合s用来保存已求得的最短路径的终点序号,初始时s=[vi]表示只有源点,以后每求出一个终点vj就把它加入到集合中并作为新考虑的中间结点。
设数组dist[1..n]用来存储当前求得的最短路径,初始时vi,vj如果是关联的,则dist[j]=权值,否则=maxint,以后,随着考虑的中间结点越来越多,dist[j]可能越来越小。再设一个与dist数组相对应的数组path[1..n],用path[j]来存放当前vi-vj的最短路径上vj点的前驱,初始时为vi的边,如果不存在边,则为0。
执行时,先从s以外的顶点(即待求出最短路径的终点)所对应的dist数组元素中,找出其值最小的元素(假设为dist[m]),该元素的值就是从源点vi到终点vm的最短路径长度,从对应的path[m]中的顶点开始递归直到源点的序列即为最短路径。接着把vm并入集合s中,然后以vm作为新考虑的中间结点,对s以外的每个顶点vj,比较dist[m]+GA[m,j]和dist[j]的大小,若前者小,表明加入中间结点后可以得到更好的方案,即可求得更短的路径,那么就用dist[m]+GA[m,j]替代原来的dist[j],同时把vm存入到path[j]中。重复以上n-2次,即可在dist数组得到从源点到其余各终点的最短路径长度,对应的path数组中保存着相应的最短路径的终点前驱。
算法执行过程图示分析:
•
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int map[1000][1000]; 6 int vis[1000]; 7 int dis[1000]; 8 int path[1000]; 9 int n,m,w; 10 int e; 11 const int maxn=999999; 12 void df(int); 13 void print(int, int); 14 int main() 15 { 16 cin>>n>>m; 17 memset(dis,maxn,sizeof(dis)); 18 memset(map,maxn,sizeof(map)); 19 for(int i=1;i<=m;i++) 20 { 21 int x,y; 22 cin>>x>>y>>w; 23 map[x][y]=map[y][x]=w; 24 } 25 memset(vis,0,sizeof(vis)); 26 int a; 27 cin>>a>>e; 28 df(a); 29 print(a,e); 30 } 31 void df(int s) 32 { 33 for(int i=1;i<=n;i++) 34 { 35 dis[i]=map[s][i]; 36 if(dis[i]!=maxn) 37 { 38 path[i]=s; 39 } 40 else path[i]=0; 41 } 42 vis[s]=1; 43 dis[s]=0; 44 int k,min1; 45 for(int i=1;i<=n-1;i++) 46 { 47 k=s; 48 min1=maxn; 49 for(int j=1;j<=n;j++) 50 { 51 if(dis[i]<min1&&vis[j]==0) 52 { 53 min1=dis[i]; 54 k=j; 55 } 56 } 57 vis[k]=1; 58 for(int q=1;q<=n;q++) 59 { 60 if(vis[q]==0&&dis[q]>dis[k]+map[k][q]) 61 { 62 dis[q]=dis[k]+map[k][q]; 63 path[q]=k; 64 } 65 } 66 } 67 cout<<dis[e]<<" "; 68 } 69 void print(int u,int r) 70 { 71 int que[1000]; 72 int tot=1; 73 int temp; 74 que[tot]=r; 75 tot++; 76 temp=path[r]; 77 while(temp!=u) 78 { 79 que[tot]=temp; 80 tot++; 81 temp=path[temp]; 82 } 83 que[tot]=u; 84 for(int i=tot;i>=1;i--) 85 { 86 cout<<que[i]<<"-->"; 87 } 88 }
以上是关于Dijkstra算法O (N2)的主要内容,如果未能解决你的问题,请参考以下文章