《啊哈!算法》第6章最短路径

第一节 Floyd-Warshall算法

本算法可以求任意两个点之间的最短路径,又称“多源最短路径”,其时间复杂度为O(n^3)

其核心部分只有下面几行,注意加法的溢出处理

    //floyd最短路径算法的核心部分
    for(int k = 0; k < n; ++ k){
        for(int i = 0 ; i < n ; ++ i){
            for(int j = 0 ; j < n ; ++ j){
                if(grid[i][k]!=INT_MAX && grid[k][j]!=INT_MAX &&grid[i][j] > grid[i][k]+grid[k][j]){
                    grid[i][j] = grid[i][k] + grid[k][j];
                    path[i][j] = k;
                }
            }
        }
    }

/*
 *基于有向图的floyd最短路径算法
 *floyd算法不能解决带有“负权回路”的图
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <cstdio>
using namespace std;

typedef vector<vector<int> > VVI;

void floyd(VVI& grid, VVI& path){
    int n = grid.size();
    //floyd最短路径算法的核心部分
    for(int k = 0; k < n; ++ k){
        for(int i = 0 ; i < n ; ++ i){
            for(int j = 0 ; j < n ; ++ j){
                if(grid[i][k]!=INT_MAX && grid[k][j]!=INT_MAX &&grid[i][j] > grid[i][k]+grid[k][j]){
                    grid[i][j] = grid[i][k] + grid[k][j];
                    path[i][j] = k;
                }
            }
        }
    }
}

void print(int x, int y, VVI& path){
   int k = path[x][y];
   //cout<<"k="<<k<<endl;
   if(k==-1) return;
   print(x,k,path);
   printf("%d->",k);
   print(k,y,path);
}

int main(){
    int n,m;
    cin >> n >> m;
    VVI grid(n,vector<int>(m,INT_MAX));
    for(int i = 0 ; i < n; ++ i) grid[i][i] = 0;
    for(int i = 0 ; i < m; ++ i){
        int a,b,e;
        cin >> a >> b >> e;
        grid[--a][--b] = e;
    }
    VVI path(n,vector<int>(m,-1));
    floyd(grid,path);
    //输出最终的结果
    cout<<string(30,‘=‘)<<endl;
    printf("start\tend\tlength\tpath\n");
    for(int i = 0 ; i < n ; ++ i){
        for(int j = 0 ;  j < n; ++ j){
            printf("%4d\t%4d\t%4d\t",i+1,j+1,grid[i][j]);
            printf("%d->",i+1);
            print(i,j,path);
            printf("%d\n",j+1);
        }
        //printf("\n");
    }
    cout<<string(30,‘=‘)<<endl;
    return 0;
}

floyd最短路径算法

第二节 Dijkstra算法-通过边实现松弛

《啊哈!算法》第6章最短路径

时间: 2024-08-24 07:48:28

《啊哈!算法》第6章最短路径的相关文章

Dijkstra算法求单源最短路径

1.最短路径 在一个连通图中,从一个顶点到另一个顶点间可能存在多条路径,而每条路径的边数并不一定相同.如果是一个带权图,那么路径长度为路径上各边的权值的总和.两个顶点间路径长度最短的那条路径称为两个顶点间的最短路径,其路径长度称为最短路径长度. 最短路径在实际中有重要的应用价值.如用顶点表示城市,边表示两城市之间的道路,边上的权值表示两城市之间的距离.那么城市A到城市B连通的情况下,哪条路径距离最短呢,这样的问题可以归结为最短路径问题. 求最短路径常见的算法有Dijkstra算法和Floyd算法

算法导论 第一章

算法导论 第一章,为了让自己基本功更加的扎实,从今天起开始学习算法导论. 我以一位学长的博客为学习的参考资料,开始我的学习吧! 附上一句话: Having a solid base of algorithm knowledge and technique is one characteristic that separates the truly skilled programmers from the novices. 是否具有扎实的算法知识和技术基础,是区分真正熟练的程序员与新手的一项重要特

普林斯顿公开课:算法第0章,课程介绍

课程介绍 这门课程核心内容是算法和数据结构. 具体的算法和数据结构如下: 数据类型:堆栈.队列.背包.并查集.优先队列. 排序:快排.并排.堆排.基数排序 查找:BST.红黑BST.哈希表 图:BFS.DFS.Prim.Kruskai.Dijkstra 字符串:KMP.正则.TST.哈夫曼.LZW 高级:B树.后缀数组.最大流 为什么要学习算法 算法在各个领域中都有应用. 算法可以提高编程效率. 算法可以将现实生活中的物理公式转换成代码,算法可以模拟现实世界,然后发现世界的奥秘. 算法是很有趣的

算法导论 第二章

2014-12-02 20:21:40 http://www.cnblogs.com/sungoshawk/p/3617652.html 上面链接指向算法导论第二章的预习博客,很值得一看,很详细. 插入算法: 1 #include <iostream> 2 3 using namespace std; 4 void insert_sort(int *datas, int length); 5 int main() 6 { 7 int a[10]={1,2,4,35,6,1,4,7,9,7};

数据结构与算法问题 单源最短路径 浙大OJ

题目描述: 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. 输入: 输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p.最后一行是两个数 s,t;起点s,终点t.n和m为0时输入结束. (1<n<=1000, 0<m<100000, s != t) 输出: 输出 一行有两个数, 最短距离及其花费. 样例输入: 3 2

算法-迪杰斯特拉算法(dijkstra)-最短路径

迪杰斯特拉算法(dijkstra)-最短路径 简介: 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 算法思想: 设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中

怎样通过boost库的breadth_first_search算法查找点到点的最短路径

From:http://stackoverflow.com/questions/8950188/is-it-possible-to-apply-breadth-first-search-algorithm-of-boost-library-to-matri/8953750#8953750 我的任务是找出矩阵中一个点到另一个点的最短路径,且只能按照上下左右移动 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 F 0 0 1 0 1 0 0 0 0 0 0 0

算法第三章上机实验

算法第三章上机实验 数字三角形 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. #include <iostream> using namespace std; int maxsum(int a[100][100],int n){ int b[100][100]={0}; for(int i=n-1;i>=0;i--){ for(int j=i;j>=0;j--){

【算法总结】图论-最短路径

[算法总结]图论-最短路径 一.概念 最短路径问题.即寻找图中某两个特定结点间最短的路径长度.所谓图上的路径,即从图中一个起始结点到一个终止结点途中经过的所有结点序列,路径的长度即所经过的边权和. 二.Floyd算法 用邻接矩阵保存原图,那么此时邻接矩阵中 edge[i][j]的值即表示从结点 i 到 结点j,中间不经过任何结点时距离的最小值(若它们之间有多条边,取最小权值保存至邻接矩阵:也可能为无穷,即不可达).假设结点编号为 1 到 N,我们再考虑从结点i 到结点j中间只能经过编号小于等于1