Dijkstra 算法的复杂性

2023-11-27

我从许多来源了解到,如果使用简单的方法来获取最小元素(线性搜索),Dijkstra 的最短路径也将以 O(V^2) 复杂度运行。但是,如果使用优先级队列,则可以优化为 O(VLogV),因为该数据结构将在 O(1) 时间内返回 min 元素,但在删除 min 元素后需要 O(LogV) 时间来恢复堆属性。

我已在以下链接中针对 UVA 问题的代码中实现了 Dijkstra 算法::

#include<iostream>
#include<vector>
#include <climits>
#include <cmath>
#include <set>

using namespace std;

#define rep(a,b,c) for(int c=a;c<b;c++)

typedef std::vector<int> VI;
typedef std::vector<VI> VVI;

struct cmp {
    bool operator()(const pair<int,int> &a,const pair<int,int> &b) const {
        return a.second < b.second;
    }
};

void sp(VVI &graph,set<pair<int,int>,cmp> &minv,VI &ans,int S,int T) {
    int e = -1;
    minv.insert(pair<int,int>(S,0));
    rep(0,graph.size() && !minv.empty() && minv.begin()->first != T,s) {
        e = minv.begin()->first;
        minv.erase(minv.begin());
        int nb = 0;
        rep(0,graph[e].size(),d) {
            nb = d;
            if(graph[e][d] != INT_MAX && ans[e] + graph[e][d] < ans[d]) {
                set<pair<int,int>,cmp>::iterator si = minv.find(pair<int,int>(d,ans[d]));
                if(si != minv.end())
                    minv.erase(*si);
                ans[d] = ans[e] + graph[e][d];
                minv.insert(pair<int,int>(d,ans[d]));
            }
        }
    }
}

int main(void) {
    int cc = 0,N = 0,M = 0,S = -1,T = -1,A=-1,B=-1,W=-1;
    VVI graph;
    VI ans;
    set<pair<int,int>,cmp> minv;
    cin >> cc;

    rep(0,cc,i) {
        cin >> N >> M >> S >> T;
        graph.clear();
        ans.clear();
        graph.assign(N,VI());
        ans.assign(graph.size(),INT_MAX);
        minv.clear();
        rep(0,N,j) {
            graph[j].assign(N,INT_MAX);
        }
        ans[S] = 0;
        graph[S][S] = 0;
        rep(0,M,j) {
            cin >> A >> B >> W;
            graph[A][B] = min(W,graph[A][B]);
            graph[B][A] = min(W,graph[B][A]);
        }
        sp(graph,minv,ans,S,T);
        cout << "Case #" << i + 1 << ": ";
        if(ans[T] != INT_MAX)
            cout << ans[T] << endl;
        else
            cout << "unreachable" << endl;
    }
}

根据我的分析,我的算法具有 O(VLogV) 复杂度。 STL std::set 是作为二叉搜索树实现的。此外,该集合也已排序。 因此从中获取最小元素是 O(1),插入和删除各是 O(LogV)。然而,我仍然从这个问题中得到一个 TLE,根据给定的时间限制,这个问题应该可以在 O(VLogV) 中解决。

这让我进行了更深入的思考。如果所有节点都互连,使得每个顶点 V 都有 V-1 个邻居怎么办?由于每个顶点每轮都必须查看 V-1,V-2,V-3...节点,这不会使 Dijkstra 算法在 O(V^2) 中运行吗?

再想一想,我可能误解了最坏情况的复杂性。有人可以就以下问题向我提供建议吗:

  1. 考虑到上述反例,Dijkstra 算法 O(VLogV) 有何特别之处?
  2. 如何优化我的代码,使其实现 O(VLogV) 复杂度(或更好)?

Edit:

我意识到我的程序毕竟不能在 O(ElogV) 中运行。瓶颈是由我的输入处理造成的,它的运行时间为 O(V^2)。 dijkstra 部分确实运行在 (ElogV) 中。


为了理解 Dijkstra 算法的时间复杂度,我们需要研究在用于实现 Frontier 集的数据结构上执行的操作(即用于实现 Frontier 集的数据结构)minv在你的算法中):

  • Insert
  • Update
  • 查找/删除最小值

O(|V|)插入物,O(|E|)更新,O(|V|)查找/删除在算法的整个持续时间内数据结构上出现的总数的最小值。

  • 最初,Dijkstra 使用未排序的数组实现了 Frontier 集。原来是这样O(1)用于插入和更新,但是O(|V|)对于查找/删除最小值,导致O(|E| + |V|^2), 但是由于|E| < |V|^2, 你有O(|V|^2).

  • 如果使用二进制最小堆来实现 Frontier 集,则有log(|v|)对于所有操作,导致O(|E|log|V| + |V|log|V|),但由于可以合理地假设|E| > |V|, 你有O(|E|log|V|).

  • 然后是斐波那契堆,在这里你有O(1)插入/更新/查找最小的摊销时间,但是O(log|V|)删除最小值的摊销时间,为您提供当前最知名的时间范围O(|E| + |V|log|V|)对于 Dijkstra 算法。

最后,解决单源最短路径问题的算法O(|V|log|V|)最坏情况的时间复杂度是不可能的,如果(|V|log|V| < |E|),因为问题的时间下限很简单O(|E| + |V|)也就是说,您需要至少检查每个顶点和边一次才能解决问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dijkstra 算法的复杂性 的相关文章

  • std::list::clear 是否会使 std::list::end 迭代器无效?

    检查这个代码 include stdafx h include
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • Nullable 是不可能的,为什么不呢? [复制]

    这个问题在这里已经有答案了 如果这是一个愚蠢的问题 请原谅 我正在尝试更好地理解 Net 中的 Nullable 类型 从我从 Microsoft 源代码 使用 ReSharper 中注意到的内容 我了解到 Nullable 是一个结构 而
  • EventHandler 应该始终用于事件吗?

    我一直在愉快地使用自定义委托类型和通用编写事件Action委托类型 没有真正考虑我在做什么 我有一些很好的扩展助手Action and EventHandler这使我倾向于使用那些预定义的委托类型而不是我自己的委托类型 但除此之外 除了惯例
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • 如何使用 C# 以编程方式编辑 Power BI Desktop 文档参数或数据源?

    我有一个在 Power BI Desktop 中内置的报告模板 并保存为 pbix 或 pbit 文件 该模板使用DirectQuery SQL数据库作为数据源 而服务器地址和数据库名称被提取到参数中 还有一个参数包含一个ReportId
  • 如何调整 Windows 窗体以适应任何屏幕分辨率?

    我知道这是重复的问题 但我检查了所有其他相关问题 他们的答案没有帮助 结果仍然与屏幕截图 2 中所示相同 我是 C Windows 窗体新手 如截图1所示 我有Form1有一些控件 每组控件都放在一个面板中 我在 PC1 中设计了应用程序
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 类中是否可以有虚拟类声明?

    我正在为个人项目中框架的各个组件设置一个接口 我突然想到了一些我认为可能对接口有用的东西 我的问题是这是否可能 class a public virtual class test 0 class b public a public clas
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • 提升mapped_file_source、对齐方式和页面大小

    我正在尝试在性能很重要的上下文中解析一些大小高达几百兆字节的文本文件 因此我使用 boostmapped file source 解析器期望源以空字节终止 因此我想检查文件大小是否是页面大小的精确倍数 如果是 则使用较慢的非内存映射方法 我
  • 如果在代码中添加元素,“FindName”将不起作用

    在 WPF 应用程序中 如果在 XAML 中声明 ContentControl
  • 如何使用 C# 查询远程 MS ACCESS .mdb 数据库

    我正在尝试使用 C 查询 mote MS ACCESS 数据库 mdb 文件 将文件复制到本地计算机时可以成功查询它 我只想远程放置文件 所以我的客户端程序不包含原始数据 static string m path http www xyz
  • 在 C++ 代码 gdb 中回溯指针

    我在运行 C 应用程序时遇到段错误 在 gdb 中 它显示我的一个指针位置已损坏 但我在应用程序期间创建了 10 万个这样的对象指针 我怎样才能看到导致崩溃的一个 我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗 谢谢 鲁奇 据我
  • 如何对STL向量进行排序?

    我想排序一个vector vector
  • 解释这段代码的工作原理;子进程如何返回值以及在哪里返回值?

    我不明白子进程如何返回该值以及返回给谁 输出为 6 7 问题来源 http www cs utexas edu mwalfish classes s11 cs372h hw sol1 html http www cs utexas edu
  • 绘制多边形

    我正在使用 Google Maps API V3 根据路径绘制多边形 该路径是随机未排序坐标点 LatLng 的数组 这会产生以下形状 Polylines intersect Problem 由于多边形的形状取决于路径中点的顺序 因此如何对
  • Emacs C++,打开相应的头文件

    我是 emacs 新手 我想知道 是否有在头文件 源文件和相应的源文件 头文件之间切换的快捷方式 是否有像通用 emacs 参考卡那样的参考卡 Thanks There s ff find other file 您可以使用以下方法将其绑定到

随机推荐

  • Java继承

    为什么最后打印的是 我是一个儿童班 public class Parent String parentString public Parent System out println Parent Constructor public Par
  • jQuery 无限函数执行

    我们想知道是否可以有一个使用 jQuery 的函数来检查多个元素 并根据通过单击分配给它们的类型来执行其他函数 基本上 这是一个将永远运行的函数 而用户不会刷新页面 这个想法不是依赖事件点击来执行功能 而是依赖分配给特定元素的类 例如 td
  • 如何在 Java 日期和儒略日数之间进行转换? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 Java 怎样才能Date被转换成double代表儒略日 如何将儒略日数转换为JavaD
  • 如何更改 xtable markdown 中某些单元格的颜色?

    我有一个名为 j 的数据框 dput j structure list Trans c 89 8 3337 NA 97 55 NA 3558 7 NA 4290 6 NA 65 95 94 55 3495 9 CPU c 6 938 79
  • 无法在 Google App Engine 上部署 java 项目

    我已在 Google App Engine 上创建了一个项目 但无法使用项目 id 部署该项目 我的项目 id 以下是发生问题的详细信息 您选择的应用程序 ID 我的项目 ID 不存在 去http cloud google com cons
  • 重新加载 Bootstrap 自定义

    On http getbootstrap com customize 可以创建和下载自定义引导程序配置 下载中包含一个名为 config json 的文件 是否可以以某种方式使用该文件来重新填充值并调整自定义引导配置 如果没有 有人知道为什
  • CodeIgniter 调用模型如何查看?

    我有一个包含数据表的视图 该数据是在模型上生成的 我如何在我的视图中调用此模型以发布在我的视图上 这相当于我想在 php 上使用 codeIgniter 做的事情 while row mysql fetch array requet cod
  • Laravel 每日日志使用错误的权限创建

    我有一个使用 php artisan 运行的脚本 带有rootuser 有时它会导致每日日志文件在apache之前创建www data用户这样做 这意味着当真正的用户使用我的网络应用程序时 我收到文件夹权限错误 无法打开流 权限被拒绝 我将
  • int (*p) [4]?

    int p 4 p 指针是指向 4 个整数的数组吗 或者是什么 以及如何为该指针调用 新 p 指针是指向 4 个整数的数组吗 Correct 我怎样才能为这个指针调用 new 例如 p new int 7 4
  • Canvas getImageData() 以获得最佳性能。提取所有数据还是一次提取一个数据?

    我需要扫描画布图像中的每个像素 并对颜色等进行一些处理 为了获得最佳性能 我是否应该一次性获取所有数据并通过数组对其进行处理 或者我应该在处理每个像素时调用它 所以基本上 data context getImageData x y heig
  • jQuery ajax 循环内问题

    这个js循环脚本总是获取jquery ajax函数内ui item的最后一个值 如何捕获每次迭代的正确值 for var i 0 i lt split files cb value holder length 1 i var split v
  • 是否可以让 Jackson 将嵌套对象序列化为字符串

    鉴于这些课程 Value private static class Message private final String type private final MyType message Value public class MyTy
  • 您可以以其他用户身份使用 files.upload 将文件上传到 Slack API 吗?

    我正在尝试找到一种方法 让应用程序通过 Slack API 将文本片段发布到我们的支持渠道 使用 files upload 方法 我可以创建一个文本片段并将其与频道共享 但该帖子似乎来自我 因为用于验证请求的令牌是我的 我正在寻找一种方法来
  • 分配以数字结尾的 CSS 字体系列

    所以看来 如果我分配一个以数字结尾的字体系列 它就不会粘住 a document createElement div a style fontFamily Arial 那么 a 就是 div style font family Arial
  • QueryDSL - 如何加入子查询的联合

    我正在使用 QueryDSL 构建一个 SQL 查询 其中包含多个联合起来的子查询 这是我的查询的基础 QTransaction t QTransaction transaction query query from t where t t
  • Firebase 无提示通知不会启动关闭的 iOS 应用程序

    FCM 无提示通知可以启动关闭的 iOS 应用程序吗 Request Type POST Request URL https fcm googleapis com fcm send Request Headers Authorization
  • 如何使用 GCC 4.8 配置 libstdc++?

    不久前 我决定升级到 GCC 4 8 以便尽早开始使用一些 c 11 功能 不过 我有点偏离主题 直到几天前的一个项目才真正使用任何新功能 新编译器似乎工作正常 但这可能只是因为我没有使用任何新功能 在这个新项目中 当我使用 std c 1
  • 为什么在 MNIST 分类器代码中使用 X[0] 会出现错误?

    我正在学习使用 MNIST 数据集进行分类 我遇到了一个错误 我无法弄清楚 我已经做了很多谷歌搜索 但我无能为力 也许你是专家并且可以帮助我 这是代码 gt gt gt from sklearn datasets import fetch
  • 如何去除 IE9 中链接周围的蓝色边框?

    我正在这个网站上工作 http amberdreams com 这是一个非常简单的网站 我一直在使用 netrenderer com 来确保所有页面都可以在 Internet Explorer 中运行 尽管我尽了最大努力 但在使用 Inte
  • Dijkstra 算法的复杂性

    我从许多来源了解到 如果使用简单的方法来获取最小元素 线性搜索 Dijkstra 的最短路径也将以 O V 2 复杂度运行 但是 如果使用优先级队列 则可以优化为 O VLogV 因为该数据结构将在 O 1 时间内返回 min 元素 但在删