代码随想录算法训练营第五十九天|图论part9

dijkstra(堆优化版)精讲

文章讲解:代码随想录

题目链接:47. 参加科学大会(第六期模拟笔试)

operator()函数调用运算符重载(Function Call Operator Overload),它让一个对象可以像函数一样被调用。

std::priority_queue<T, Container, Compare> 中,三个模板参数的含义如下 :

默认是大顶堆

T:元素类型

Container:底层容器类型

Compare:比较器

朴素迪杰斯特拉算法:

1.选取距离源节点并且未访过的节点

2.标记选取节点为已访问

3.更新权重

现在改为用邻接链表去存储图

list是双向链表

不支持随机访问

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <list>
#include <climits>

//用来方便定义邻接链表
using namespace std;
struct Edge{
    int to,val;
    Edge(int _to,int _val):to(_to),val(_val){}
};
struct cmp{
    bool operator()(pair<int,int>a,pair<int,int>b){
        return a.second>b.second;
    }
};


int main(){
    int n,m;
    cin>>n>>m;
    vector<list<Edge>>grid(n+1);//邻接链表
    for(int i=0;i<m;i++){
        int s,e,v;
        cin>>s>>e>>v;
        grid[s].push_back(Edge(e,v));
    }

    int start=1;
    int end=n;
    vector<int>minDist(n+1,INT_MAX);
    vector<bool>isVisited(n+1,false);

    //优先队列 存储节点及节点到源点的距离
    priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>pq;
    minDist[start]=0;
    pq.push({start,0});

    while(!pq.empty()){
        //取最近点
        auto cur=pq.top();
        pq.pop();
        if(isVisited[cur.first])continue;
        //标记为已读
        isVisited[cur.first]=true;
        //更新minDist数组
        list<Edge> edges=grid[cur.first];
        for(auto it=edges.begin();it!=edges.end();it++){
            if(!isVisited[it->to]&&minDist[cur.first]+it->val<minDist[it->to]){
                minDist[it->to]=minDist[cur.first]+it->val;
                pq.push({it->to,minDist[it->to]});
            }
        }
    }

    if(minDist[end]==INT_MAX) cout<<-1;
    else cout<<minDist[end];

}

Bellman_ford

题目链接: 94. 城市间货物运输 I

文章讲解: 代码随想录

带有负权值的单源最短路径

核心思想:

对所有边进行n-1次松弛操作

cpp 复制代码
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>>grid;
    while(m--){
        int s,t,v;
        cin>>s>>t>>v;
        grid.push_back({s,t,v});
    }
    vector<int>minDist(n+1,INT_MAX);
    minDist[1]=0;
    for(int i=1;i<n;i++){
        for(int j=0;j<grid.size();j++){
            int s=grid[j][0];
            int t=grid[j][1];
            int val=grid[j][2];
            if(minDist[s]==INT_MAX)continue;
            minDist[t]=min(minDist[s]+val,minDist[t]);
        }
    }
    if(minDist[n]!=INT_MAX){cout<<minDist[n];}
    else cout<<"unconnected";
}