图论----最短路径

来源:互联网 发布:无主之地2汉化补丁 mac 编辑:程序博客网 时间:2024/05/14 07:01

1、Floyd算法

       原理:图中任意两点之间的最短距离等于两点之间的直接距离和经过其他中间节点的距离之和的最小距离,即D[i][j] = min{ D[i][j] , D[i][k] + D[k][j] },Floyd通常用来求所有顶点到所有顶点的最短路径。

代码如下:

#include "stdafx.h"#include <iostream.h>#include <stdlib.h>#pragma warning(disable:4786)#include <queue>#include <stack>#include <set>#include <vector>using namespace std;const int n=5;void ShortestPath_Floyd(int a[][n],int D[][n],int P[][n]){int i,j,k;//初始化for (i=0;i<n;i++)for (j=0;j<n;j++){D[i][j]=a[i][j];P[i][j]=j;}for (k=0;k<n;k++)for(i=0;i<n;i++)for (j=0;j<n;j++)if(D[i][j]>D[i][k]+D[k][j]){D[i][j]=D[i][k]+D[k][j]; //更新最小权值和     P[i][j]=P[i][k];         //更新路径}}int main(int argc, char* argv[]){//邻接矩阵5*5,节点0~8int a[n][n]={0,1,4,30,5,1,0,10,37,2,4,10,0,20,12,3,3,20,0,15,5,2,12,15,0};int P[n][n]; //保存最短路径节点int D[n][n]; //保存最短路径权值和int k;ShortestPath_Floyd(a,D,P);//打印最短路径for (int i=0;i<n;i++){for (int j=i+1;j<n;j++){cout<<"v"<<i<<"-"<<"v"<<j<<" weight: "<<D[i][j];k=P[i][j];cout<<"\tpath: "<<i;while(k!=j){cout<<" -> "<<k;k=P[k][j];}cout<<" -> "<<j<<endl;}cout<<endl;}return 0;}

2、Dijkstra算法

原理;D算法并不是一下子就求出顶点v0到vi的最短路径,而是一步步先求出他们之间的顶点的最短路径,过程中都是基于已经求出的最短路径基础上,求得更远顶点的最短路径,最终得到结果。

#include "stdafx.h"#include <iostream.h>#include <stdlib.h>#pragma warning(disable:4786)#include <queue>#include <stack>#include <set>#include <vector>using namespace std;const int n=5;const int MAXVEX=65536;void ShortestPath_Dijkstra(int a[][n],int v0,int D[n],int P[n]){int i,j,k,min=MAXVEX;int final[n]; //标记是否已求得最短路径//初始化for(i=0;i<n;i++){final[i]=0;D[i]=a[v0][i];P[i]=0;}D[v0]=0; //v0到v0路径为0final[v0]=1;//循环找出v0到某个顶点v的最短路径for (i=0;i<n;i++){min=MAXVEX;for (j=0;j<n;j++){if (!final[j]&&D[j]<min){min=D[j]; //j节点距离v0更近k=j;}}final[k]=1; //标记已访问过//修正当前最短最短距离for (j=0;j<n;j++){if (!final[j]&&(min+a[k][j])<D[j]){P[j]=k;D[j]=min+a[k][j];}}}}int main(int argc, char* argv[]){//邻接矩阵5*5,节点0~8int a[n][n]={0,1,4,30,5,1,0,10,37,2,4,10,0,20,12,3,3,20,0,15,5,2,12,15,0};int P[n]; //保存最短路径节点int D[n]; //保存最短路径权值和int v0=0; //起始节点int k[n],j=0;ShortestPath_Dijkstra(a,v0,D,P);//打印最短路径for (int i=0;i<n;i++){cout<<"v0-v"<<i<<" weight: "<<D[i];cout<<"\tpath:v0";k[j]=P[i];while(k[j]!=0){k[j+1]=P[k[j]];j++;}//采用逆向输出数组内容打印最短路径for(j--;j>=0;j--)    cout<<"->v"<<k[j];j=0;cout<<"->v"<<i<<endl;}cout<<endl;return 0;}