博客
关于我
G. Reducing Delivery Cost(思维+最短路)
阅读量:242 次
发布时间:2019-03-01

本文共 2202 字,大约阅读时间需要 7 分钟。

如何优化处理免费边对最短路径的影响

在处理图中存在免费边的情况下,找到所有点对的最短路径是一个具有挑战性的任务。传统的方法可能需要对每条边进行暴力枚举,然后针对每个点进行Dijkstra算法,这种方法的时间复杂度通常较高。以下是一种优化的方法,能够有效地处理这种情况,同时减少计算量。

方法概述

我们提出了一种基于预处理的方法,通过分析每条边对各个点对的最短路径的影响,来找到最优解。具体步骤如下:

  • 预处理每个点的最短路径:对于图中的每个点,使用Dijkstra算法计算其到所有其他点的最短路径。这样可以得到一个全面的距离矩阵。

  • 分析每条边的影响:对于每条边(a, b),我们需要分析其对不同点对的最短路径的影响。具体分为以下三种情况:

    • 情况1:边(a, b)不在任何点对的最短路径上,添加后仍然不在任何最短路径上。
    • 情况2:边(a, b)不在原来的最短路径上,但添加后可能进入另一个最短路径。
    • 情况3:边(a, b)原本就在某些点对的最短路径上,添加后可能改变这些点对的最短路径。
  • 计算最小值:对于每条边,计算其对所有点对的最短路径的影响,然后取最小值作为最终结果。

  • 这种方法的时间复杂度为O(mk + n² log m),其中m是边的数量,n是点的数量,k是需要处理的点对数量。这比传统的暴力枚举方法更高效。

    具体实现步骤

  • 预处理最短路径:使用Dijkstra算法对图中的每个点进行一次计算,得到一个距离矩阵f[i][j],表示点i到点j的最短路径距离。

  • 遍历每条边:对于每条边(a, b),考虑其对点对的最短路径的影响。具体来说,对于每条边,计算其对所有点对的最短路径的影响,然后更新最终的最短路径距离。

  • 更新最终结果:对于每条边,计算其对所有点对的最短路径的影响,然后取最小值作为最终结果。

  • 代码示例

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #define debug(a) cout << a << endl;using namespace std;const int maxn = 1e3 + 100;typedef long ll;typedef pair
    P;LL n, m, k, start;struct edge { LL to, cost;};vector
    g[maxn];vector
    > Edge;void dijkstra() { LL s = start; memset(dis, 0x3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[s] = 0; priority_queue
    , greater

    > que; que.push({0, s}); while (!que.empty()) { P p = que.top(); que.pop(); LL v = p.second; if (vis[v]) continue; vis[v] = 1; for (LL i = 0; i < g[v].size(); i++) { edge e = g[v][i]; if (dis[e.to] > dis[v] + e.cost) { dis[e.to] = dis[v] + e.cost; que.push({dis[e.to], e.to}); } } } for (LL j = 1; j <= n; j++) { f[s][j] = dis[j]; }}int main() { cin.tie(0); std::ios::sync_with_stdio(false); cin >> n >> m >> k; vector

    > v; for (LL i = 1; i <= k; i++) { LL a, b; cin >> a >> b; v.push_back({a, b}); } for (LL i = 1; i <= n; i++) { start = i; dijkstra(); } LL sum = 1e18; for (auto i : Edge) { LL a = i.first, b = i.second; LL ans = 0; for (auto j : v) { LL u = j.first, w = j.second; LL option1 = f[u][u] + f[u][a] + f[w][b]; LL option2 = f[u][u] + f[u][b] + f[w][a]; ans += min(f[u][w], option1, option2); } sum = min(sum, ans); } cout << sum << endl;}

    总结

    通过预处理每个点的最短路径,并分析每条边对点对的最短路径的影响,我们可以有效地找到图中所有点对的最短路径,即使存在大量免费边的情况。这种方法的时间复杂度优于传统的暴力枚举方法,使得处理大规模图问题更加高效。

    转载地址:http://twct.baihongyu.com/

    你可能感兴趣的文章
    non linear processor
    查看>>
    Non-final field ‘code‘ in enum StateEnum‘
    查看>>
    none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)
    查看>>
    None还可以是函数定义可选参数的一个默认值,设置成默认值时实参在调用该函数时可以不输入与None绑定的元素...
    查看>>
    NoNodeAvailableException None of the configured nodes are available异常
    查看>>
    Vue.js 学习总结(16)—— 为什么 :deep、/deep/、>>> 样式能穿透到子组件
    查看>>
    nopcommerce商城系统--文档整理
    查看>>
    NOPI读取Excel
    查看>>
    NoSQL&MongoDB
    查看>>
    NoSQL介绍
    查看>>
    NoSQL数据库概述
    查看>>
    Notadd —— 基于 nest.js 的微服务开发框架
    查看>>
    NOTE:rfc5766-turn-server
    查看>>
    Notepad ++ 安装与配置教程(非常详细)从零基础入门到精通,看完这一篇就够了
    查看>>
    Notepad++在线和离线安装JSON格式化插件
    查看>>
    notepad++最详情汇总
    查看>>
    notepad++正则表达式替换字符串详解
    查看>>
    notepad如何自动对齐_notepad++怎么自动排版
    查看>>
    Notes on Paul Irish's "Things I learned from the jQuery source" casts
    查看>>
    Notification 使用详解(很全
    查看>>