priority queue 优化的 dijkstra 算法

本文探讨了如何使用priority queue优化Dijkstra算法,以提高寻找最短路径的效率。通过结合vector存储图,实现了更高效的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dijkstra 算法是非常常用的最短路算法,所以它的效率至关重要;

这里采用vector进行图的存储,概念比较简单易懂,同时效率也还可观;





struct Edge
{
    int from;//出发结点
    int to;//终止结点
    int dist;//距离
    Edge(int u,int v,int d):from(u),to(v),dist(d){}
};

struct HeapNode
{
    int d,u;//d为距离,u为起始结点
    //重载运算符
    bool operator < (const HeapNode& rhs) const
    {
        return d>rhs.d;
    }
};

struct Dijkstra
{
    int n;//n为结点数
    int m;//m为边的编号
    vector<Edge> edges;
    vector<int> G[maxn];
    bool done[maxn];//是否已经标记过
    int d[maxn];//源点到各个点的距离
    int p[maxn];//最短路中的上一条弧

    void init(int n)
    {
        this->n=n;
        for(int i=0;i<n;++i)
        {
            G[i].clear();
        }
        edges.clear();
    }

    void AddEdge(int from,int to,int dist)
    {
        edges.push_back(Edge(from,to,dist));
        m=edges.size();
        //把边的编号压入,相当于邻接表
        G[from].push_back(m-1);
    }

    void dijkstra(int s)
    {
        priority_queue<HeapNode> Q;
        for(int i=0;i<n;++i)
            d[i]=INF;
        d[s]=0;
        memset(done,0,sizeof(done));
        Q.push((HeapNode){0,s});
        while(!Q.empty())
        {
            HeapNode x=Q.top();
            Q.pop();
            int u=x.u;
            if(done[u]) continue;
            done[u]=true;
            for(int i=0;i<G[u].size();++i)
            {
                Edge& e=edges[G[u][i]];
                if(d[e.to]>d[u]+e.dist)
                {
                    d[e.to]=d[u]+e.dist;
                    p[e.to]=G[u][i];
                    Q.push((HeapNode){d[e.to],e.to});
                }
            }
        }
    }
};


在提供的代码中,采用了双向搜索的方式来优化Dijkstra算法。具体实现如下: 1. **初始化**: - 从起点 `s` 和终点 `v` 分别启动两个Dijkstra算法- 创建两个距离数组 `d1` 和 `d2`,分别存储从起点和终点到其他点的最短距离。 - 创建两个前驱数组 `pre1` 和 `pre2`,分别存储从起点和终点到其他点的前驱节点。 - 使用优先队列 `pq1` 和 `pq2` 来优化Dijkstra算法的搜索过程。 2. **双向Dijkstra算法**: - 从起点 `s` 开始执行Dijkstra算法,更新 `d1` 和 `pre1`。 - 从终点 `v` 开始执行Dijkstra算法,更新 `d2` 和 `pre2`。 3. **寻找汇合点**: - 遍历所有节点,找到一个节点 `i`,使得 `d1[i] + d2[i]` 最小。这个节点即为汇合点 `meetPoint`。 - 如果找不到这样的节点,说明从 `s` 到 `v` 没有路径。 4. **输出结果**: - 如果找到了汇合点,分别从起点 `s` 到汇合点 `meetPoint` 和从终点 `v` 到汇合点 `meetPoint` 构建最短路径,并输出路径及其长度。 - 将路径和路径长度写入文件 `result.txt`。 - 计算并输出程序的运行时间。 以下是关键代码段: ```cpp int main() { clock_t start_time = clock(); string filename = "C:/Users/19867/Desktop/instance.txt"; vector<int> numbers = filedeal::readline(filename); int s, n, v; n = numbers[0]; s = numbers[1]; v = numbers[2]; vector<vector<double>> matrix = filedeal::readmatrix(filename, n); vector<vector<double>> G = matrix; vector<int> d1(n, inf), d2(n, inf); vector<int> pre1(n), pre2(n); priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq1, pq2; Dijkstra(n, s, G, d1, pre1, pq1); Dijkstra(n, v, G, d2, pre2, pq2); int meetPoint = -1; double minDistance = inf; for (int i = 0; i < n; ++i) { if (d1[i] + d2[i] < minDistance) { minDistance = d1[i] + d2[i]; meetPoint = i; } } if (meetPoint == -1) { cout << "从 " << s << " 到 " << v << " 没有路径!" << endl; } else { cout << "从 " << s << " 到 " << v << " 的最短路径为:" << endl; DFSPrint(s, meetPoint, pre1, minDistance); DFSPrint(v, meetPoint, pre2, minDistance); cout << endl << "路径长度之和为: " << fixed << setprecision(2) << minDistance << endl; } clock_t end_time = clock(); double run_time = (double)(end_time - start_time) / CLOCKS_PER_SEC * 1000; ofstream resultFile; resultFile.open("C:/Users/19867/Desktop/result.txt", ofstream::app); if (!resultFile.is_open()) { cout << "无法打开文件!" << endl; return -1; } resultFile << "程序运行时间为: " << fixed << setprecision(2) << run_time << " ms" << endl; resultFile.close(); cout << "程序运行时间为: " << run_time << " ms" << endl; return 0; } ``` 通过双向搜索,可以显著减少搜索空间,从而提高算法的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值