2.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的前驱节点,用来输出路径。
1 #include<cstdio> 2 #include<cstring> 3 #define N 1010 4 #define MAXX 9999999 5 int dis[N]; 6 int map[N][N]; 7 int qq[N]; 8 int que[N]; 9 int n,m,bein,s,ss; 10 int visit[N]; 11 void work(int s) 12 { 13 visit[s]=1; 14 for(int k=1;k<=n;++k) 15 { 16 dis[k]=map[s][k]; 17 if(map[s][k]!=MAXX)qq[k]=s; 18 else qq[k]=0; 19 } 20 visit[s]=1; 21 dis[s]=0; 22 for(int I=1;I<n;++I) 23 { 24 int k=s,minn=MAXX; 25 for(int j=1;j<=n;++j) 26 { 27 if(!visit[j]&&dis[j]<minn) 28 { 29 minn=dis[j]; 30 k=j; 31 } 32 } 33 visit[k]=1; 34 for(int i=1;i<=n;++i) 35 { 36 if(map[k][i]&&!visit[i]&&dis[i]>dis[k]+map[k][i]) 37 { 38 dis[i]=dis[k]+map[k][i]; 39 qq[i]=k; 40 } 41 } 42 } 43 printf("%d ",dis[ss]); 44 } 45 void print (int u,int v ) 46 { 47 int tot=1; 48 que[tot]=v; 49 tot++; 50 int temp=qq[v]; 51 while(temp!=u) 52 { que[tot]=temp; 53 tot++; 54 temp=qq[temp]; 55 } 56 que[tot]=u; 57 for(int i=tot;i>=1;i--) 58 if(i!=1) 59 printf("%d->",que[i]); 60 else 61 printf("%d",que[i]); 62 63 } 64 int main() 65 { 66 scanf("%d%d",&n,&m); 67 memset(dis,MAXX,sizeof(dis)); 68 memset(map,MAXX,sizeof(map)); 69 for(int i=1;i<=m;++i) 70 { 71 int x,y,q; 72 scanf("%d%d%d",&x,&y,&q); 73 map[x][y]=q; 74 map[y][x]=q; 75 } 76 scanf("%d%d",&s,&ss); 77 work(s); 78 print(s,ss); 79 return 0; 80 }