zoukankan      html  css  js  c++  java
  • Floyd算法

    传送门:

     Dijkstra

     Bellman-Ford

     SPFA

     Floyd

    1.算法思想:

    定义一个n阶方阵序列:A(-1) A(0) A(1) A(2) ....... A(n-1)

    A(-1) [i][j]表示顶点Vi到顶点Vj的直接边的长度,A(-1) 就是邻接矩阵Edge[n][n]

    A(0) [i][j]表示顶点Vi到顶点Vj,中间顶点(如果有,则)是V0的最短路径长度

    A(1) [i][j]表示顶点Vi到顶点Vj,中间顶点序号不大于1的最短路径长度

    A(2) [i][j]表示顶点Vi到顶点Vj,中间顶点序号不大于2的最短路径长度

    A(n-1) [i][j]表示顶点Vi到顶点Vj最短路径长度

    允许带有负权值的边,但不能有负权值回路。

    2.代码实现

    输入:

    4 8
    0 1 1
    0 3 4
    1 2 9
    1 3 2
    2 0 3
    2 1 5
    2 3 8
    3 2 6

    输出:

    0->1    1       0->1
    0->2    9       0->1->3->2
    0->3    3       0->1->3
    1->0    11      1->3->2->0
    1->2    8       1->3->2
    1->3    2       1->3
    2->0    3       2->0
    2->1    4       2->0->1
    2->3    6       2->0->1->3
    3->0    9       3->2->0
    3->1    10      3->2->0->1
    3->2    6       3->2

    递推式a[i][j] = min(a[i][j], a[i][k] + a[k][j])

    如果只是判断连通性,可改成a[i][j] |= a[i][k] & a[k][j];

    此处存路径是按照倒叙存储路径path[i][j]表示从顶点vi到vj的最短路径上顶点j的前一个点的序号,这里有正序存路径使得字典序最小,而且这里必须在初始化的时候初始化path,如果有边就要初始化。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<set>
    10 #include<sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn = 1000 + 10;
    14 const int INF = 1 << 25;
    15 int T, n, m, cases;
    16 int Map[maxn][maxn];//存图
    17 int path[maxn][maxn];//存路径,path[i][j]表示从顶点vi到vj的最短路径上顶点j的前一个点的序号
    18 int a[maxn][maxn];//存最短路径长度
    19 void Floyd()
    20 {
    21     for(int i = 0; i < n; i++)
    22     {
    23         for(int j = 0; j < n; j++)
    24         {
    25             for(int k = 0; k < n; k++)
    26             {
    27                 a[i][j] = Map[i][j];
    28                 if(i != j && a[i][j] < INF)path[i][j] = i;//i到j有路径
    29                 else path[i][j] = -1;//从i到j没有直接的路径
    30             }
    31         }
    32     }
    33     for(int k = 0; k < n; k++)
    34     {
    35         for(int i = 0; i < n; i++)
    36         {
    37             for(int j = 0; j < n; j++)
    38             {
    39                 if(k == i || k == j)continue;
    40                 if(a[i][k] + a[k][j] < a[i][j])
    41                 {
    42                     a[i][j] = a[i][k] + a[k][j];
    43                     path[i][j] = path[k][j];
    44                 }
    45             }
    46         }
    47     }
    48     for(int i = 0; i < n; i++)
    49     {
    50         for(int j = 0; j < n; j++)
    51         {
    52             if(i == j)continue;
    53             printf("%d->%d	%d	", i, j, a[i][j]);
    54             stack<int>q;
    55             int x = j;
    56             while(x != -1)
    57             {
    58                 q.push(x);
    59                 x = path[i][x];
    60             }
    61             cout<<q.top();
    62             q.pop();
    63             while(!q.empty())
    64             {
    65                 cout<<"->"<<q.top();
    66                 q.pop();
    67             }
    68             cout<<endl;
    69         }
    70     }
    71 }
    72 int main()
    73 {
    74     cin >> n >> m;
    75     for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)Map[i][j] = (i == j ? 0 :INF);
    76     int u, v, w;
    77     for(int i = 0; i < m; i++)
    78     {
    79         cin >> u >> v >> w;
    80         Map[u][v] = w;
    81     }
    82     Floyd();
    83     return 0;
    84 }
  • 相关阅读:
    TextWatcher 监视EditText的输入
    【Android】SqLitOpenHelper操作数据库
    【第一个开源项目】最完整的Andoird联系人操作,完美支持联系人的各种属性操作。
    Ext.ux.grid.RowEditor更新
    『转』如何判断Store加载完毕
    MyEclipse8.6安装svn插件
    『转』Eclipse中设置编码的方式
    『转』jsonlib json 格式 Date
    Spring Security的关键组件
    Ext.grid之numbercolumn格式化输出
  • 原文地址:https://www.cnblogs.com/fzl194/p/8729340.html
Copyright © 2011-2022 走看看