代码随想录算法训练营第五十九天|图论part9
dijkstra(堆优化版)精讲
文章讲解:代码随想录
题目链接:47. 参加科学大会(第六期模拟笔试)
operator()
是 函数调用运算符重载(Function Call Operator Overload),它让一个对象可以像函数一样被调用。
std::priority_queue<T, Container, Compare>
中,三个模板参数的含义如下 :
默认是大顶堆
T:元素类型
Container:底层容器类型
Compare:比较器
朴素迪杰斯特拉算法:
1.选取距离源节点并且未访过的节点
2.标记选取节点为已访问
3.更新权重
现在改为用邻接链表去存储图
list是双向链表
不支持随机访问
#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次松弛操作
#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";
}