最短路径---Floyd-Warshall,Dijkstra,Bell-man
2018-02-07 21:02
393 查看
Floyd-Warshall的基本思想: 通过一个中转点不断地来松弛顶点的出边
Dijkstra的基本思想:找到已知最短路径的顶点,利用该顶点不断地松弛顶点的出边
Bell-man:
显然,Bellman算法是可以进行优化的,因为每一次实施松弛操作后,就会有一些顶点已经求得了其最短路,此后这些顶点的最短路的估计值就会一直保持不变,不再收到后续松弛操作的影响,但是每次仍需要判断是否需要松弛,所以浪费了时间.所以我们每次仅对最短路估计值发生变化了的顶点的所有出边执行松弛操作.
8fff
//Floyd-Warshall算法核心语句 for (int k = 1; k <= V; k++) for (int i = 1; i <= V; k++) for (int j = 1; j <= V; j++) if ( e[i][j] > e[i][k] + e[k][j] ) e[i][j] = e[i][k] + e[k][j]
/* *最短路径---Floyd-Warshall算法 *2018/2/7 */ #include <bits/stdc++.h> using namespace std; const int maxn = 101; const int inf = 10001; int e[maxn][maxn], V, E; void pf() { for (int i = 1; i <= V; i++) { for (int j = 1; j <= V; j++) { cout << e[i][j] << " "; } cout << endl; } } int main() { int dis, t1, t2, t3; //录入顶点和边的个数 cin >> V >> E; //初始化邻接矩阵 for (int i = 1; i <= V; i++) for (int j = 1; j <= V; j++) if ( i == j ) e[i][j] = 0; //自己到自己的距离为0 else e[i][j] = inf; //否则为无穷大 //录入边 for (int i = 1; i <= E; i++) { cin >> t1 >> t2 >> t3; e[t1][t2] = t3; } //利用Floyd-Warshall算法算出最短路径 // k为中转点 for (int k = 1; k <= V; k++ ) { for (int i = 1; i <= V; i++) { for (int j = 1; j <= V; j++) { dis = e[i][k] + e[k][j]; //记录利用中转点后i到j的距离 if ( dis < e[i][j] ) { e[i][j] = dis; pf(); system("pause"); } } } } /** 4 8 1 2 2 1 3 6 1 4 4 2 3 3 3 1 7 3 4 1 4 1 5 4 3 12 **/ return 0; }
Dijkstra的基本思想:找到已知最短路径的顶点,利用该顶点不断地松弛顶点的出边
/* *最短路径---Dijkstra算法 *2018/2/7 */ #include <bits/stdc++.h> using namespace std; const int maxn = 101; const int inf = 10001; int e[maxn][maxn], dis[maxn], book[maxn], V, E; void pf() { for (int i = 1; i <= V; i++) { for (int j = 1; j <= V; j++) { cout << e[i][j] << " "; } cout << endl; } } int main() { int t1, t2, t3, n; int minsub, min_e; //录入顶点和边的个数 cin >> V >> E; //初始化邻接矩阵 for (int i = 1; i <= V; i++) for (int j = 1; j <= V; j++) if ( i == j ) e[i][j] = 0; //自己到自己的距离为0 else e[i][j] = inf; //否则为无穷大 //录入边 for (int i = 1; i <= E; i++) { cin >> t1 >> t2 >> t3; e[t1][t2] = t3; } //输入需要求最短路径的顶点 cin >> n; //初始化dis数组,该数组表示n号顶点到其余顶点的初始距离 for (int i = 1; i <= V; i++) dis[i] = e [i]; //初始化book数组,用来标记该顶点有没有被使用过 for (int i = 1; i <= V; i++) book[i] = 0; book = 1; //Dijkstra算法核心语句 for (int i = 1; i <= V - 1; i++) { //找到离顶点n最近的点 min_e = inf; for (int j = 1; j <= V; j++) { if ( book[j] == 0 && dis[j] < min_e ) { min_e = dis[j]; minsub = j; } } book[minsub] = 1; for (int j = 1; j <= V; j++) { if ( dis[j] > dis[minsub] + e[minsub][j] ) dis[j] = dis[minsub] + e[minsub][j]; } } //打印顶点n到各个顶点的最短路径 for (int i = 1; i <= V; i++) cout << dis[i] << " "; /** 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4 1 */ return 0; }
Bell-man:
/* *最短路径---Bellman(表男)算法 *2018/2/7 */ #include <bits/stdc++.h> using namespace std; const int maxe = 1001, maxv = 1001, inf = 10001; struct edge { int from, to, cost; }; int dis[maxv], V, E; edge e[maxe]; int main() { bool check = true; //用于判断是否需要继续松弛 int n; //输入顶点与边的个数 cin >> V >> E; //录入边 for (int i = 1; i <= E; i++) cin >> e[i].from >> e[i].to >> e[i].cost; //输入要求最短路径的顶点 cin >> n; //初始化dis数组 for (int i = 1; i <= V; i++) dis[i] = inf; dis = 0; //表男算法核心语句 for (int i = 1; i <= V - 1 && check == true; i++) { check = false; for (int j = 1; j <= E; j++) if ( dis[e[j].to] > dis[e[j].from] + e[j].cost ) { cout << dis[e[j].to] << " " << dis[e[j].from] << " " << dis[e[j].cost] << endl; dis[e[j].to] = dis[e[j].from] + e[j].cost; check = true; } } //检测负权回路 for (int i = 1; i <= E; i++) if ( dis[e[i].to] > dis[e[i].from] + e[i].cost ) { cout << "该图存在负权回路" << endl; break; } //输出结果 for (int i= 1; i <= V; i++) cout << dis[i] << " "; return 0; }
显然,Bellman算法是可以进行优化的,因为每一次实施松弛操作后,就会有一些顶点已经求得了其最短路,此后这些顶点的最短路的估计值就会一直保持不变,不再收到后续松弛操作的影响,但是每次仍需要判断是否需要松弛,所以浪费了时间.所以我们每次仅对最短路估计值发生变化了的顶点的所有出边执行松弛操作.
8fff
相关文章推荐
- 最短路径 -- Floyd-Warshall & Dijkstra & spfa 学习和思考
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson
- 多路径路由算法选择(7)——最短路径算法Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson,无一幸免
- [图的最短路径算法]Dijkstra, Bellman-Ford, Floyd-Warshall
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson
- Dijkstra/Floyd-Warshall 最短路径算法
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最短路径算法Dijkstra && SPFA && Floyd 代码实现模板
- 最短路径 (单源最短路径Dijkstra和任意两点最短路径Floyd) C实现
- POJ 1125 Stockbroker Grapevine (最短路径.Floyd-Warshall)
- 最短路径算法----Dijkstra Bellman-Ford Floyd-Warshall Johnson
- 【算法】最短路径-弗洛伊德(Floyd-Warshall)
- 图论算法(二)-最短路径的Dijkstra [ 单源 ] 和Floyd[ 多源 ] 解法(JAVA )
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- Dijkstra单源最短路径实现 及 Floyd任意两点之间的最短路径
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- 所有节点对的最短路径之Floyd-Warshall
- 【算法导论】【Floyd-Warshall 算法】每对节点之间的最短路径