d.重复步骤b和c直到所有顶点都包含在S中。
代码:
//最短路径之Dijkstra算法 void dijkstra(grap&g,int v){ int lowcost[M];//v到某节点权 int pre[M];//前驱节点 bool u[M];//节点是否包含 int i,j,k; int t; int min; for(i=0;i<g.v;i++){ lowcost[i]=g.edge[v][i]; u[i]=0; if(lowcost[i]!=0)pre[i]=v; else pre[i]=-1; } cout<<"最短路径节点集:"<<endl; lowcost[v]=0; u[v]=1; cout<<v<<"->"; for(i=0;i<g.v-1;i++){ min=INF; t=v; for(j=0;j<g.v;j++){ if(u[j]==0&&min>lowcost[j]&&lowcost[j]!=0){t=j;min=lowcost[j];} } u[t]=1; cout<<t<<"->"; for(k=1;k<g.v;k++){ if(u[k]==0&&(g.edge[t][k]!=0)){ if(lowcost[k]==0)lowcost[k]=lowcost[t]+g.edge[t][k]; else if((lowcost[t]+g.edge[t][k])<lowcost[k]){lowcost[k]=lowcost[t]+g.edge[t][k];pre[k]=t;} }} } cout<<endl; for(i=0;i<g.v;i++){ cout<<v<<"到节点"<<i<<"距离:"<<lowcost[i]<<endl;} }
Floyd算法
1.定义概览
Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd-Warshall算法的时间复杂度为O(N3),空间复杂度为O(N2)。
2.算法描述
1)算法思想原理:
Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
2).算法描述:
a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。
代码://最短路径之Floyd算法 void Floyd(grap&g){ int a[M][M];//任意两点之间最短距离 int path[M][M];//更改的位置 int i,j,k; int t; int min; for(i=0;i<g.v;i++) for(j=0;j<g.v;j++){if(i==j)a[i][j]=g.edge[i][j]; else if(g.edge[i][j]==0)a[i][j]=INF; else a[i][j]=g.edge[i][j]; path[i][j]=-1;}//初值 for(k=0;k<g.v;k++) { for(i=0;i<g.v;i++) for(j=0;j<g.v;j++) if(a[i][j]>a[i][k]+a[k][j]){a[i][j]=(a[i][k]+a[k][j]);path[i][j]=k;} }//核心 if(a[i][j]>a[i][k]+a[k][j]){a[i][j]=(a[i][k]+a[k][j]);path[i][j]=k;} for(i=0;i<g.v;i++){ for(j=0;j<g.v;j++) cout<<a[i][j]<<" "; cout<<endl;} }