• [模板]Floyd多源最短路 P2910


    参考此文

    Floyd利用动态规划暴力计算多源点间最短路.

    通过枚举"中转站",并枚举所有可行的起点和终点,检查通过此中转站能否得到此起点终点的更短路径.O(N3).

    由于其复杂度较大(因而只能处理小数据)且需要同时检查中转站的父节点和子节点,适合用邻接矩阵处理.

    (带权图,边权可正可负,不存在的路径初始化为INF)
    for (int k = 1; k <= n; ++k) // 中转站 for (int i = 1; i <= n; ++i) // 起点 if (i != k) for (int j = 1; j <= n; ++j) // 终点 if (i != j && j != k) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    进行Floyd处理后,dist[i][j]即表示节点 i 到节点 j 的最短距离.

    为什么要把中转站放在最外层呢?看看别人的博客:

     (图即链接)

    不能处理有负权回路的图.


     

    这里的每一个节点到任意一个其他节点都是有一条有向边的,存图和算距离可以在同一个数组中操作.

    只需Floyd先算出任意两点间的最短路,再累加给定的序列中相邻两点的最短路即可.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n, m, dist[110][110], s[10010];
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) scanf("%d", s + i);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) scanf("%d", &dist[i][j]);
    
        for (int k = 1; k <= n; ++k)
            for (int i = 1; i <= n; ++i)
                if (i != k)
                    for (int j = 1; j <= n; ++j)
                        if (i != j && j != k)
                            dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
    
        int ans = 0;
        for (int i = 1; i < m; i++) ans += dist[s[i]][s[i + 1]];
    
        printf("%d
    ", ans);
    
        return 0;
    }
    P2910
  • 相关阅读:
    4-vim-工作模式-01-职责以及切换模式
    3-vim-打开和新建文件-02-删除交换文件
    poj1011Stick(dfs+剪枝)
    POJ 1251 Jungle Roads (prim)
    poj 2502 Subway
    poj 3624 Charm Bracelet (01背包)
    拦截导弹问题(动态规划)
    Policy Gradient
    深入了解马尔科夫决策过程(Markov Decision Process)
    深度学习中调参对模型容量的影响
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14447928.html
Copyright © 2020-2023  润新知