P3371 单源最短路径
模版:
看了几个版本的dijkstra,最终以如下代码作为板子。
看如下代码之前,你需要先学这两位大佬的课程
前提: D=<V,E>且w_i>=0
优化:if(dis>d[u1]) continue;
合法性:
d[v1] = d[u1] + w1实时更新为更小值
↓pq.push({d[v1], v1})压入新的(更小的)距离
↓- 堆中关于
v1的条目:旧的(大)vs 新的(小)
↓ - 最小堆保证:小的先弹出,大的后弹出
↓ - 先弹出的:
dis == d[v1](当前最小)→ 处理
后弹出的:dis > d[v1](已过时) → 跳过
断言:弹出的一定只可能是dis>=d[u1].
反证:假设弹出 (dis, u) 且 dis < d[u].
d[u]是当前已知最短距离dis < d[u]意味着存在更短路径- 但
Dijkstra性质:第一次弹出时d[u]已确定,不可能有更短的 - 矛盾!
模版:
#include<bits/stdc++.h>
#define N 10005
#define INF LLONG_MAX
using namespace std;
using ll=long long;
struct edge{ll v,w;};
vector<edge> e[N];
priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> pq;
ll d[N];//,vis[N];
ll n,m,s,u0,v0,w0;
void dijkstra()
{
for(ll i=1;i<=n;++i) d[i]=INF;
d[s]=0;
pq.push({0,s});
while(!pq.empty()){
auto head=pq.top(); pq.pop();
ll u1=head.second,d1=head.first;
if(d1>d[u1]) continue;
for(auto ed:e[u1]){
ll v1=ed.v,w1=ed.w;
if(d[u1]+w1<d[v1]){
d[v1]=d[u1]+w1;
pq.push({d[v1],v1});
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(ll i=1;i<=m;++i){
cin>>u0>>v0>>w0;
e[u0].push_back({v0,w0});
}
dijkstra();
for(ll i=1;i<=n;++i){
if(d[i]==LLONG_MAX) d[i]=INT_MAX;
cout<<d[i]<<" ";
}
return 0;
}

浙公网安备 33010602011771号