您的位置:首页 > 其它

贪心算法——单源最短路径

2016-04-28 12:28 411 查看

1.问题描述

给定一个带权有向图G={V,E},以及V中的一个顶点,称为源,计算从源到其他各顶点的最短路径。

2.Dijkstra算法

Dijkstra算法是解单源最短路径的一个贪心算法,其主要思想是:设置顶点集合S,并不断地扩充该集合S,一个点可以归并到该集合的充要条件是该点到源点的距离已知。用数组dist记录目前所有点到该点的最短路径,循环依次找出不在该集合中的(V-S)点到源点路径最短的点加入该集合(注意:数组dist记录的是所有点到源点的最短路径,在该集合(S)中的点到源点的最短路径是可能会经过S中的顶点的最短路径,V-S中的点到源点的目前最短距离是距离从该点到源点的直接路径长短)。每当加入一个新点v1,就对数组dist做必要的修改(比较源点到v1的最短路径加上v1到该点的最短路径和源点不通过v1到该点的最短路径,如果前者更短,则更新数组dist中对应的值为前者的值),依次循环直到所有的点都在集合S中(S=V),则数组dist即为其他点到源点的最短路径。

1.c++代码:

用邻接矩阵存储有向图各边的权信息。

头文件

#include <iostream>
using namespace std;
#define NUM 10                  //最大顶点个数
#define INFINITY 100000         //路径最长不超过


图的顶点定义

typedef struct ArcCell{          //顶点信息
int adj;
char  *info;
}ArcCell,AdjMatrix[NUM][NUM];


MGaph类

class MGaph
{
private:
int vexnum;         //图的顶点数
int arcnum;         //弧的数量
AdjMatrix arcs;     //图的邻接矩阵
char  vexs[NUM];    //图的顶点向量
int lovatevex(char c)  //确定输入的顶点的位置
{
int i;
for(i=0;i<vexnum;i++)
if(vexs[i]==c)
return i;
return i;
}
<span style="color:#ff0000;">void shortestpath(int v0)
{
bool final[vexnum],p[vexnum][vexnum];      //p[i][j]表示到达i要经过j
int  d[vexnum],v;                          //数组d用来存放最终的结果
for(int i=0;i<vexnum;i++)///初始化
{
final[i]=false;
d[i]=arcs[v0][i].adj;
for(int j=0;j<vexnum;j++)
p[i][j]=false;
if(d[i]<INFINITY)
p[i][v0]=true,p[i][i]=true;
}
for(int i=1;i<vexnum;i++)                   //分别求剩下个点到已知点的最短路径
{
int min=INFINITY;
for(int j=0;j<vexnum;j++)                    //找出距离集合S最短的顶点
if(!final[j])
if(d[j]<min)
v=j,min=d[j];
final[v]=true;                                 //将该点并入集合S
for(int j=0;j<vexnum;j++)                      //更新所有点到远点的距离
if(!final[j]&&(min+arcs[v][j].adj<d[j]))
{
d[j]=min+arcs[v][j].adj;
p[j][j]=true;
}
}
for(int i=0;i<vexnum;i++)
if(i!=v0)
{
cout<<vexs[v0]<<"---"<<vexs[i]<<"  ";
if(d[i]==INFINITY)
cout<<"无法到达"<<endl;
else cout<<d[i]<<endl;
}
}</span>
public:
MGaph(int v0)             //构造函数
{
char c1,c2;
int n;
cout<<"输入顶点数和弧数:"<<endl;
cin>>vexnum>>arcnum;
for(int i=0;i<vexnum;i++)
for(int j=0;j<vexnum;j++)
arcs[i][j].adj=INFINITY,arcs[i][j].info=NULL;
cout<<"输入顶点名(字母表示):"<<endl;
for(int i=0;i<vexnum;i++)
cin>>vexs[i];
cout<<"输入弧和弧的权(用两个顶点名表示弧):"<<endl;
for(int m=0;m<arcnum;m++)
{
cin>>c1>>c2>>n;
int i=lovatevex(c1);
int j=lovatevex(c2);
arcs[i][j].adj=n;
}
shortestpath(v0);
}
};
红色标记部分为 Dijkstra算法的思想。

main函数

int main()
{
MGaph G(0);
return 0;
}




2.复杂度分析:

对于一个有n个顶点e条边的带权有向图,主体循环部分需要O(n)时间,执行n-1次,所以完成整个循环需要O(n*n)时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: