博客
关于我
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/

    你可能感兴趣的文章
    PIPE 接口信号列表
    查看>>
    pipeline配置与管理Job企业级实战
    查看>>
    pipeline项目配置实战
    查看>>
    Pipenv 与 Conda?
    查看>>
    QVGA/HVGA/WVGA/FWVGA分辨率屏含义及大小//Android虚拟机分辨率
    查看>>
    pipreqs : 无法将“pipreqs”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径 正确,然后再试一次。
    查看>>
    pipy国内镜像的网址
    查看>>
    quiver绘制python语言
    查看>>
    pip下载缓慢
    查看>>
    PIP使用SSH从BitBucket安装自定义软件包,无需输入SSH密码
    查看>>
    pip在安装模块时提示Read timed out
    查看>>
    pkl来存储python字典
    查看>>
    quick sort | 快速排序 C++ 实现
    查看>>
    pkpmbs 建设工程质量监督系统 文件上传漏洞复现
    查看>>
    pku 2400 Supervisor, Supervisee KM求最小权匹配+DFS回溯解集
    查看>>
    queue队列、deque双端队列和priority_queue优先队列
    查看>>
    PKUSC2018游记
    查看>>
    PK项目测试,做产品测试有这4大优势!
    查看>>
    pl sql 的目录 所在的目录 不能有 小括号,如 Program Files (x86)
    查看>>
    PL SQLDEVELOPMENT导出数据库脚本
    查看>>