带权有向图最短路径
来源:互联网 发布:电子商城微信源码 编辑:程序博客网 时间:2024/06/06 01:00
1、适用条件&范围:
1)单源最短路径(从源点s到其它所有顶点v);
2)有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图)
3)所有边权非负(任取(i,j)∈E都有Wij≥0);
2、算法描述:
在带权图中最常遇到的问题就是,寻找两点间的最短路径问题。最著名的算法是Djikstra算法。这个算法的实现基于图的邻接矩阵表示法,它不仅能够找到任意两点的最短路径,还可以找到某个指定点到其他所有顶点的最短路径。
此算法的基本思想是:
1>选中指定的顶点,列出此顶点到其他的顶点的权值,不相邻的为无穷大2>从以上权值中选出最小值,此最小值就是起始点到对应顶点的最短路径,并标记这个对应顶点
3> 将起始点到其他未标记的顶点的直接距离与起始点到刚才标记顶点加上标记顶点到其他顶点距离的和比较,如果 后者小,则更新对应的权值。
4> 转2
3、程序实现代码:
#include <iostream>#include <iomanip>using namespace std; #include "Graph.h" void main(){ int i, n; cout << "输入你所输入的有向带权图的顶点个数: "; cin >> n; adjmatrix g; InitMatrix(g); CreateMatrix(g); cout << "你输入的有向带权图的邻接矩阵表示为: " << endl; PrintMatrix(g, n); int * d = new int [n]; edgenode ** path = new edgenode * [n]; cout << "请输入你要输入的源点: "; cin >> i; Dijkstra(g, d, path, i, n); PrintPath(d, path, i, n);} //***********Graph.h**********************#define MaxVerNum 20#define MaxValue 10000typedef int adjmatrix[MaxVerNum][MaxVerNum]; //邻接矩阵的类型定义 typedef struct Node{ int adjvex; struct Node * next;}edgenode; //指针数组path[]基类型定义 //初始化邻接矩阵表示的有向带权图void InitMatrix(adjmatrix G){ int i, j; for(i = 0; i < MaxVerNum; i++) for(j = 0; j < MaxVerNum; j++) G[i][j] = MaxValue;} //建立邻接矩阵表示的有权带向图(即通过输入图的每条边建立图的邻接矩阵)void CreateMatrix(adjmatrix G){ int i, j, x; cout << "请输入顶点和相应的权值: " << endl; cin >> i >> j >> x; while(i != -1) { G[i][j] = x; cin >> i >> j >> x; }} //输出邻接矩阵表示的有向带权图(即输出图的每条边)void PrintMatrix(adjmatrix G, int n){ int i, j; for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { if(G[i][j] == MaxValue) cout << setiosflags(ios::left) << setw(5) << "Inf"; else cout << setiosflags(ios::left) << setw(5) << G[i][j]; } cout << endl; }} void Path(edgenode * path[], int m, int j){ edgenode * p, * q, *s; p = path[j]; while(p != NULL) { path[j] = p->next; delete p; p = path[j]; } p = path[m]; while(p != NULL) { q = new edgenode; q->adjvex = p->adjvex; if(path[j] == NULL) path[j] = q; else s->next = q; s = q; p = p->next; } q = new edgenode; q->adjvex = j; q->next = NULL; s->next = q;} //求最短路径的Dijkstral算法void Dijkstra(adjmatrix GA, int dist[], edgenode *path[], int i, int n){ int j, k, w, m; bool * s = new bool[n]; for(j = 0; j < n; j++) { if(j == i) s[j] = true; else s[j] = false; dist[j] = GA[i][j]; if(dist[j] < MaxValue && j != i) { edgenode * p1 = new edgenode; edgenode * p2 = new edgenode; p1->adjvex = i; p2->adjvex = j; p2->next = NULL; p1->next = p2; path[j] = p1; } else path[j] = NULL; } for(k = 1; k <= n-2; k++) { w = MaxValue; m = i; for(j = 0; j < n; j++) if(s[j] == false && dist[j] < w) { w = dist[j]; m = j; } if(m != i) s[m] = true; else break; for(j = 0; j < n; j++) if(s[j] == false && dist[m] + GA[m][j] < dist[j]) { dist[j] = dist[m]+GA[m][j]; Path(path, m, j); } } delete []s;} //输出从源点到每个顶点的最短路径及长度的函数void PrintPath(int dist[], edgenode * path[], int i, int n){ int j; for(j = 0; j < n; j++) { if(i != j) { cout << "顶点v" << i << "到顶点v" << j << "的最短路径的长度为 " << dist[j] << ", 最短路径为: "; edgenode * p = path[j]; while(p != NULL) { cout << setw(4) << p->adjvex; p = p->next; } cout << endl; } }}程序运行结果:
输入你所输入的有向带权图的顶点个数: 6
请输入顶点和相应的权值:
0 1 10
0 2 12
1 3 16
1 4 25
2 0 4
2 1 3
2 3 12
2 5 8
3 4 7
5 3 2
5 4 10
-1 2 3
你输入的有向带权图的邻接矩阵表示为:
Inf 10 12 Inf Inf Inf
Inf Inf Inf 16 25 Inf
4 3 Inf 12 Inf 8
Inf Inf Inf Inf 7 Inf
Inf Inf Inf Inf Inf Inf
Inf Inf Inf 2 10 Inf
请输入你要输入的源点: 0
顶点v0到顶点v1的最短路径的长度为 10, 最短路径为: 0 1
顶点v0到顶点v2的最短路径的长度为 12, 最短路径为: 0 2
顶点v0到顶点v3的最短路径的长度为 22, 最短路径为: 0 2 5 3
顶点v0到顶点v4的最短路径的长度为 29, 最短路径为: 0 2 5 3 4
顶点v0到顶点v5的最短路径的长度为 20, 最短路径为: 0 2 5
0 0
- 带权有向图最短路径
- 有向图最短路径
- 无向图最短路径问题
- 稀疏有向图最短路径
- Dijkstra无向图最短路径
- 带权有向图单源最短路径(Dijkstra算法)
- 带权有向图单源最短路径(Dijkstra算法)
- 无向图最短路径算法(C#)实现
- 无向图最短路径dijkstra算法
- 无向图最短路径的数目
- vijos 无向图最短路径 思维
- 有向图 路径
- 有向路径检查
- 有向路径检查
- 有向路径检查
- 有向路径检查
- 有向路径检查
- 有向路径检查
- UDP包的最大大小是多少?
- hdu1002 终于对了
- [JQuery]学习——JQuery编写性能分析
- Druid连接池入门
- 解决chrome浏览器,调试本地文件问题
- 带权有向图最短路径
- Linux Free命令与cache和buffer的主要区别
- 关于genymotion的使用
- SHELL模拟多线程脚本
- 执行redis-trib.rb时遇到的问题
- u-boot下tffp 下载与上传
- android spinner设置不全屏显示
- Cocos2d-x中的 数学函数
- 开通博客