一.Dijkstra 算法 (单源最短路径)

例题:743. 网络延迟时间

以起点 u 为中心,逐步向外扩展并更新其他顶点的「最短路径」。

「Dijkstra 算法」运用了「贪心思想」,它运行的每一步都是选择当前已知的顶点的「最小权重」去寻找其他顶点的「最短路径」。

用vector vector<pair> 存邻接表,用priority_queue维护下一个最小能更新相邻节点的值,

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        vector<vector<pair<int, int>>> g(n+1); // 邻接表 x表示出节点,g[x].first表示入节点,g[x].second表示出节点
        for (auto& t : times) {
            g[t[0]].emplace_back(t[1], t[2]);
        }
        vector<int> dis(n+1, INT_MAX);
        dis[k] = 0;
        auto cmp =[](const pair<int, int> a,const pair<int, int> b){
            return a<b;
        };
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pq(cmp); //pair<最短值,当前节点>
        pq.push({0,k});
        while(!pq.empty()){
            auto [dx,x] = pq.top();
            pq.pop();
            if(dx>dis[x]) { //已经出过堆,说明之前有更新过,不用更新了
                continue;
            }
            for(auto &[y,d]:g[x]){
                int new_dis = dx+d;
                if(new_dis<dis[y]){
                    dis[y] = new_dis;
                    pq.emplace(new_dis,y);
                }
            }
        }
        int answer = 0;
        for(int i=1;i<=n;i++){
            answer = max(answer,dis[i]);
        }
        return answer==INT_MAX?-1:answer;
    }
};

二.Kruskal 算法 (最小生成树)

例题:1584. 连接所有点的最小费用 - 力扣(LeetCode)

思路:边排序,每次加入最小边,如果成环则不加入,环的判断用并查集

class UnionFind //并查集
{
    vector<int>root;
    public:
    UnionFind (int n)
    {
        root.resize(n+1);
        for(int i = 1; i <= n ;i++) root[i] = i;
    }
    int find(int x)
    {
        return root[x] == x ? x : root[x] = find(root[x]);
    }
    void merge(int x,int y)
    {
        root[find(x)] = root[find(y)];
    }
    bool isconnect(int x,int y)
    {
        return find(x) == find(y);
    }
};

class Solution {
public://index表示并查集中的点,vector<int>存{instance,i,j};
    int minCostConnectPoints(vector<vector<int>>& points) {
        vector<vector<int>>graph;
        for(int i = 0; i < points.size(); i++)
            for(int j = i + 1; j < points.size(); j++)
            {
                int instance = get_instance(points[i],points[j]);
                graph.push_back({instance,i,j});
            }
        sort(begin(graph),end(graph),[](const auto&a,const auto&b)
        {
            return a.front() < b.front();
        });  
        UnionFind uf(points.size() + 1);
        int cnt = 0,res = 0;
        for(const auto& it : graph)
        {
            if(cnt == points.size() - 1) break;
            if(uf.isconnect(it[1],it[2]))continue;
            else
            {
                uf.merge(it[1],it[2]);
                res += it[0];
                cnt++;
            }
        }
        return res;
    }
    int get_instance(vector<int>& a,vector<int>& b)
    {
        return  abs(a[0] - b[0]) + abs(a[1] - b[1]);
    }
};