陈文忻 2023-11-24 18:27 采纳率: 60%
浏览 7

Dijkstra算法时间复杂度的提问

如题。假设一张图的点数为 n,边数为 m。
大家都说优先队列Dijkstra的时间复杂度是:

O( (m+n) log n)。

但是,看我下面的代码

#include <bits/stdc++.h>
using namespace std;
int n,m,s,u,v,w,dis[100001];
struct node
{
    int u,v;
    bool operator< (const node &a)const
    {
        return v>a.v;
    }
};
#define pi pair<int,int>
vector<pi>vec[100001];
bool vis[100001];
priority_queue<node>q;
void dij()
{
    q.push({s,0});
    while(!q.empty())
    {
        node nu=q.top();//当前点
        q.pop();
        int p=nu.u;//编号
        vis[p]=1;
        int v=nu.v;//目前的“最短”距离
        if(v>dis[p])continue;
        for(pi pu:vec[p])//枚举后面几个点 
        {
            int uu=pu.first;
            int vv=pu.second+v;
            if(uu==p||vis[uu])continue;
            if(vv<dis[uu])
            {
                dis[uu]=vv;
                q.push({uu,vv});
            }
            printf("%d\n",q.size());
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&s);//n点m边s初始
    while(m--)
    {
        scanf("%d%d%d",&u,&v,&w);//u到v权值为w
        vec[u].push_back({v,w});//插入
    }
    for(int i=1;i<=n;++i)dis[i]=2000000000;
    dis[s]=0;
    dij();
    for(int i=1;i<=n;++i)printf("%d ",dis[i]==2000000000?-1:dis[i]);
    return 0;
}

理论上来讲,一个优先队列里面最多有 m 个元素,但你只需要取出 n 个元素。所以时间复杂度不应该是O(n log m)吗?

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-11-24 20:58
    关注

    【以下回答由 GPT 生成】

    Dijkstra算法时间复杂度分析

    如果您提供了具体的数据情况以及代码片段,我们就可以根据您提供的信息来分析Dijkstra算法在该代码片段中的时间复杂度是否符合O((m+n)logn)。

    如果您暂时无法提供这些信息,我可以给您一个普遍性的结果。

    Dijkstra算法的时间复杂度通常是O((m+n)logn),其中n表示图中顶点的数量,m表示边的数量。

    下面是一个标准的Dijkstra算法的伪代码实现:

    def dijkstra(graph, start):
        # 初始化距离字典
        dist = {}
        for v in graph.keys():
            dist[v] = float('inf')
        dist[start] = 0
    
        # 初始化堆和访问集合
        heap = [(0, start)]
        visited = set()
    
        while heap:
            current_dist, current_vertex = heapq.heappop(heap)
    
            # 如果节点已经访问过,跳过
            if current_vertex in visited:
                continue
    
            # 记录节点为已访问
            visited.add(current_vertex)
    
            # 更新与当前节点相邻节点的最短距离
            for neighbor, weight in graph[current_vertex].items():
                if neighbor not in visited:
                    new_dist = current_dist + weight
                    if new_dist < dist[neighbor]:
                        dist[neighbor] = new_dist
                        heapq.heappush(heap, (new_dist, neighbor))
    
        return dist
    

    根据这段代码,我们可以进行时间复杂度分析:

    1. 初始化步骤,时间复杂度为O(n)。
    2. 在循环中,每次从堆中弹出一个顶点,时间复杂度为O(logn)。由于n个顶点每个顶点都可能会被弹出一次,所以总的时间复杂度为O(nlogn)。
    3. 在更新相邻节点最短距离的步骤中,由于需要遍历所有边,所以时间复杂度为O(m)。

    综上所述,标准的Dijkstra算法的时间复杂度为O((m+n)logn)。

    请提供具体的数据情况和代码片段,以便我们可以进一步分析和确认该代码片段中的时间复杂度。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 11月24日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见