贪心算法——单源最短路径
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)时间。相关文章推荐
- 冲刺阶段站立会议每日任务10
- java中关于容器的描述
- Node.js的TLS/SSL模块详解
- 个人工作总结10
- Quartz的cronTrigger表达式
- python遍历目录的方法小结
- HttpListenerDemo
- Android APP 设计说明书模板
- Linux下C语言Mysql数据库使用范例
- scanf和fscanf读取文件
- 虚继承
- jar命令的用法详解
- 数组方法
- 站立会议(10)
- android Uri利用及解析(文件操作)以及与路径的相互转换
- LeetCode------Excel Sheet Column Number
- 啊哈!算法—纸牌游戏—小猫钓鱼
- Linux下python安装升级详细步骤 | Python2 升级 Python3
- 啊哈!算法—栈
- 剑指offer(45):翻转句子中的单词顺序