• 多源最短路径Floyd算法


         多源最短路径是求图中任意两点间的最短路,采用动态规划算法,也称为Floyd算法。将顶点编号为0,1,2...n-1首先定义dis[i][j][k]为顶点 i 到 j 的最短路径,且这条路径只经过最大编号不超过k的顶点。于是我们最终要求的是dis[i][j][n-1].状态转移方程如下:

                 dis[i][j][k]=min{dis[i][j][k-1],dis[i][k][k-1]+dis[k][j][k-1]};

    状态转移方程的解释:在计算dis[i][j][k]的时候,我们考虑 i 到 j 是否要经过顶点 k ,若不经过顶点 k ,那么结果就是 i 到 j 的最大路径经过的最大顶点不超过 k-1,也就是dis[i][j][k-1].倘若 i 到 j 经过顶点 k,那么i到j可以分为两部分之和,即 i 到k 和 k 到 j.这时候子问题最优解是 dis[i][k][k-1]和dis[k][j][k-1],这种情况下得到的原问题最优解是dis[i][k][k-1]+dis[k][j][k-1].所以综合起来:  dis[i][j][k]=min{dis[i][j][k-1],dis[i][k][k-1]+dis[k][j][k-1]};

          在实现的时候没有必要使用三维数组。可以采用覆盖的方法:从k=0 to n-1 来计算,状态方程改变如下:

                  dis[i][j]=min{dis[i][j],dis[i][k]+dis[k][j]};

     1 #include<iostream>
     2 using namespace std;
     3 #define MAX_NUMBER INT_MAX/2
     4 #define MAX_SIZE 100
     5 struct Graph {
     6     int V, E;
     7     int R[MAX_SIZE][MAX_SIZE];
     8 };
     9 int path[MAX_SIZE][MAX_SIZE];
    10 int dis[MAX_SIZE][MAX_SIZE];
    11 void Floyd(Graph G);
    12 void PrintPath(int i, int j);
    13 int main() {
    14     Graph G;
    15     int i, j, w,k;
    16     cin >> G.V >> G.E;
    17     for (i = 0; i < G.V; i++)
    18         for (j = 0; j < G.V; j++) {
    19             G.R[i][j] = (i == j ? 0 : MAX_NUMBER);
    20             path[i][j]=i;    //假设i到j有直接路径
    21         }
    22     //--------------------------------初始化
    23     for (k = 0; k < G.E; k++) {
    24         cin >> i >> j >> w;
    25         G.R[i][j] = G.R[j][i] = w;
    26     }
    27     Floyd(G);
    28     for (i = 0; i < G.V; i++) {
    29         for (j = 0; j < G.V; j++)
    30             printf("%3d", dis[i][j]);
    31         cout << endl;
    32     }
    33     printf("
    ");
    34     for (i = 0; i < G.V; i++) {
    35         for (j = 0; j < G.V; j++)
    36             printf("%3d", path[i][j]);
    37         cout << endl;
    38     }
    39     PrintPath(0,9);
    40     return 0;
    41 }
    42 void Floyd(Graph G) {
    43     int i, j, k;
    44     for (i = 0; i < G.V; i++)
    45         for (j = 0; j < G.V; j++)
    46             dis[i][j] = G.R[i][j];         //初始化
    47     for (k = 0; k < G.V; k++)
    48         for (i = 0; i < G.V; i++)
    49             for (j = 0; j < G.V;j++)
    50                 if (dis[i][j]>dis[i][k] + dis[k][j]) {        //更新
    51                     path[i][j] = k;
    52                     dis[i][j] = dis[i][k] + dis[k][j];
    53                 }
    54 }
    55 void PrintPath(int i, int j) {
    56     if (i==j) {
    57         printf("%3d", i);
    58         return;
    59     }
    60     PrintPath(i,path[i][j]);
    61     printf("%3d", j);
    62 }
  • 相关阅读:
    PHP中可执行代码小结
    HTTP请求头列举
    GET 和 POST详解
    利用kali自带的木马工具来远程控制服务器
    利用PHP木马,远程链接服务器
    利用sqlmap暴力破解数据库密码
    MIT线性代数课程 总结与理解-第一部分
    [转]MFC debug 调试信息的输出
    关于利用均匀分布随机变量产生任意分布变量的实现
    关于string转整数
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5342507.html
Copyright © 2020-2023  润新知