最短路径算法
Posted futuresience
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路径算法相关的知识,希望对你有一定的参考价值。
(1)多源最短路径 Floyd-Warshall
算法核心语句
for(k = 1;k <= n;k++)
for(i= 1;i <= n;i++)
for(j= 1;j <= n;j++)
if(e[i][j]>e[i][k]+e[j][k])
` e[i][j] = e[i][k]+e[j][k];
例子中使用有向图来来储存边以及其权值
(2)Dijkstra算法,求一个顶点到其他顶点的最小距离
1 #include <stdio.h> 2 int main () 3 { 4 int e[10][10],dis[10],book[10],i,j,n,m,t1,t2,t3,u,v,min; 5 int inf = 99999999; 6 scanf("%d %d",&n,&m); 7 //初始化地图 8 for(i = 1;i <= n;i++) 9 for(j = 1;j <= n;j++) 10 if(i == j) e[i][j] = 0; 11 else e[i][j] = inf; 12 //读入边 13 for(i = 1;i <= m;i++) 14 { 15 scanf("%d %d %d",&t1,&t2,&t3); 16 e[t1][t2] = t3; 17 } 18 //初始化dis数据,这里的起始源点是1 19 for(i = 1;i <= n;i++) 20 dis[i] = e[1][i]; 21 //book数组初始化 22 for(i = 1;i <= n;i++) 23 book[i] = 0; 24 book[1] = 1;//标记 25 for(i = 1;i <= n-1;i++)//和prim算法相似,结合理解 26 { 27 min = inf; 28 for(j = 1;j <= n;j++) 29 { 30 if(book[j] == 0&&dis[j] < min) 31 { 32 min = dis[j]; 33 u = j; 34 } 35 } 36 book[u] = 1; 37 for(v = 1;v <= n;v++) 38 { 39 if(e[u][v]<inf) 40 { 41 if(dis[v] > dis[u]+e[u][v]) 42 dis[v] = dis[u]+e[u][v]; 43 } 44 } 45 } 46 for(i = 1;i <= n;i++) 47 printf("%d",dis[i]); 48 return 0; 49 }
通过邻接表来实现
1 int n,m,i; 2 int u[6],v[6],w[6];u,v,w,要比m的最大值要大一 3 int first[5],next[5];//first要比n的最大值要大一 4 scanf("%d %d",&n,&m); 5 for(i = 1;i <= n;i++) 6 first[i] = -1;//表示1-n点暂时没有边 7 for(i = 1;i <= n;i++) 8 {//first中的值可以理解为特定顶点的的第一条边的编号,也是该顶点最后一条读入的边 9 scanf("%d %d %d",&u[i],&v[i],&w[i]);//顶点就是读入的边的点,及u[i]
//下面两句是关键,怎样用邻接表来储存图 10 next[i] = first[u[i]];//first[u[i]]保存顶点u[i]的第一条边的编号, 11 first[u[i]] = i;//next[i]存储"编号为i的边"的下一条边 12 }//遍历某个顶点的边的顺序与读入边的顺序相反 13 14 k = first[1]; 15 while(k != -1) 16 { 17 printf("%d %d %d",&u[k],&v[k],&w[k]); 18 k = next[k]; 19 }//这里是再找到一号顶点的第一条边之后,剩下的边都可以在next数组中找到
20 for(i = 1;i <= n;i++)//邻接表的遍历 21 {//遍历每一个顶点的边 22 k = first[i]; 23 while(k != -1) 24 { 25 printf("%d %d %d",&u[k],&v[k],&w[k]); 26 k = next[k]; 27 } 28 }
以上是关于最短路径算法的主要内容,如果未能解决你的问题,请参考以下文章