算法分析设计(Floyd算法)

1. 问题

用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵),按实验报告模板编写算法。

 

 

2. 解析

3.设计

void Floyd(int n ,int m ,int path[][1000])
{
    for(int k = 1 ; k <= n ; ++ k)                               //枚举中转点,通过中转点对i,j进行松弛操作
    {
        for(int i = 1 ; i <= n ; ++ i)                       //枚举起点
        {
            for(int j = 1 ; j <= n ; ++ j)                       //枚举终点
            {
                if(path[i][k] + path[k][j] < path[i][j])         // 如果通过k节点使得 path[i][k] + path[k][j] < path[i][j] 则说明经过k节点会使得i,j之间的距离更短,更新最短距离
                    path[i][j] = path[i][k] + path[k][j];
            }
        }
    }
}
算法部分

4. 分析

时间复杂度:O(n^3)

这里需要枚举三个量,分别是中转点,起点,终点,因为三个点都属于图中的n个点,因此时间复杂度为O(n * n * n)

复杂度就是边的数量

空间复杂度:O(n ^ 2)

Floyd算法中我们用二维矩阵维护从ij的最短距离,因为需要维护任意两个节点之间的最短距离,所以所需要的空间复杂度应该是O(n * n)

 

5.代码

#include<iostream>
#include<algorithm>
#include<memory.h>
using namespace std;

const int inf = 0x3f3f3f3f;                               //inf代表无穷大,在本算法中,如果path[i][j] == inf ,那么说明从节点i出发无法到达节点j
int n, m;
int p[1000][1000];                                       //用来维护图中任意两点之间的最短距离


void Floyd(int n ,int m ,int path[][1000])
{
    for(int k = 1 ; k <= n ; ++ k)                               //枚举中转点,通过中转点对i,j进行松弛操作
    {
        for(int i = 1 ; i <= n ; ++ i)                           //枚举起点
        {
            for(int j = 1 ; j <= n ; ++ j)                       //枚举终点
            {
                if(path[i][k] + path[k][j] < path[i][j])         // 如果通过k节点使得 path[i][k] + path[k][j] < path[i][j] 则说明经过k节点会使得i,j之间的距离更短,更新最短距离
                    path[i][j] = path[i][k] + path[k][j];
            }
        }
    }
}



int main()
{

    memset(p , inf , sizeof p);                         //对图path进行初始化
    cin >> n >> m;                                      //获取节点个数和边的条数
    for(int i = 1 ; i <= n ; ++ i) p[i][i] = 0;         //一个节点到它本身的最小距离肯定是0,这里我们直接修改就好了   
    for(int i = 1 ; i <= m ; ++ i)
    {
        int u ,v , val;
        cin >> u >> v >> val;                           //获取单向边的信息
        p[u][v] = min(p[u][v] , val);                   //因为我们要求图中任意两点的最小距离,因此对于点i,j之间的路线,我们只要记录最小值即可
    }
    Floyd(n , m , p);                                    //进行Floyd
    cout << "最短距离矩阵:" << endl;
    for(int i = 1 ; i <= n ; ++ i)
    {
        for(int j = 1 ; j <= n ; ++ j)
        {
            if(p[i][j] == inf) cout << -1;              //如果p[i][j] == inf , 说明从i节点出发,无法到达j节点,这里我们用-1表示无法到达
            else cout << p[i][j];
            if(j == n) cout << endl;
            else cout << " ";
        }
    }
    return 0;
}

/*
样例:

4 8
1 2 2
2 3 3
1 3 6
3 1 7
1 4 4
4 1 5
3 4 1
4 3 12


*/
完整代码

 

原文地址:https://www.cnblogs.com/DreamACMer/p/12452599.html