ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

NC158 有向无环图的单源最短路径(C++Dijkstra算法)

2021-07-24 16:02:41  阅读:318  来源: 互联网

标签:distance pq return int 单源 C++ 环图 second vector


描述

在一个有向无环图中,已知每条边长,求出1到n的最短路径,返回1到n的最短路径值。如果1无法到n,输出-1

示例1

输入:

5,5,[[1,2,2],[1,4,5],[2,3,3],[3,5,4],[4,5,5]]

返回值:

9

备注

两个整数n和m,表示图的顶点数和边数。
一个二维数组,一维3个数据,表示顶点到另外一个顶点的边长度是多少
每条边的长度范围[0,1000]。
注意数据中可能有重边

#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;

struct Edge {
    int u, v, w;
    bool operator<(const Edge& a)const { return w < a.w; }
};


struct cmp {
    template <typename T, typename U>
    bool operator()(T const& left, U const& right) {
        // 以 second 比较。输出结果为 Second 较小的在前; Second 相同时,先进入队列的元素在前。
        if (left.second > right.second)
            return true;
        return false;
    }
};

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param n int 顶点数
     * @param m int 边数
     * @param graph intvector<vector<>> 一维3个数据,表示顶点到另外一个顶点的边长度是多少​
     * @return int
     */
    int findShortestPath(int n, int m, vector<vector<int> >& graph) {
        // write code here
        vector<vector<int>> g(n + 1, vector<int>(n + 1, INT_MAX));

        for (auto& x : graph) {
            int a = x[0], b = x[1], c = x[2];
            g[a][b] = min(g[a][b], c);  //处理重边
        }

        return dijkstra(g, n, 1, n);
    }

    int dijkstra(vector<vector<int>>& g, int n, int start, int end) {
        //基于bfs的dijkstra算法
        
        priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq; //优先级队列
        pq.push(make_pair(start, 0));

        vector<int> vis;            //访问过的节点
        map<int, int> parent;       //最短路径中的父节点

        vector<vector<pair<int, int>>> adj(n + 1);      //前驱节点链表生成
        for (int j = 1; j < g.size(); j++) {
            for (int i = 1; i < g[j].size(); i++)
            {
                if (g[j][i] < INT_MAX) 
                    adj[j].push_back(make_pair(i, g[j][i]));
            }
        }

        //初始化distance
        vector<int> distance(n + 1, INT_MAX);
        distance[start] = 0;
        for (auto& x : adj[start]) {
            distance[x.first] = x.second;
        }

        while (!pq.empty()) {
            pair<int, int> tmp = pq.top();
            pq.pop();
            int dist = tmp.second;  //距上个点的距离
            int node = tmp.first;

            vis.push_back(node);

            vector<pair<int, int>> next = adj[node];

            for (auto& x : next) {
                int i = 0;
                for (auto& v : vis) {
                    if (x.first != v) {
                        i++;
                    }
                    if (i == vis.size()) {
                        if ((dist + x.second) <= distance[x.first]) {
                            pq.push(pair<int, int>(x.first, dist + x.second));
                            parent[x.first] = node;
                            distance[x.first] = dist + x.second;
                        }
                    }
                }
            }

        }

        return distance[end];
    }

};

int main() {
    int n = 5, m = 5;
    vector<vector<int>> graph = { {1, 2, 2},{1, 4, 5},{2, 3, 3},{3, 5, 4},{4, 5, 5} };
    Solution st;
    cout << st.findShortestPath(n, m, graph);
    return 0;
}

标签:distance,pq,return,int,单源,C++,环图,second,vector
来源: https://blog.csdn.net/qq_40838478/article/details/119059549

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有