关于堆优化的Dijkstra的冗余项
//过程完全同Dijkstra I
//不同于Dijkstra I,堆不支持更新元素,
//因此,当已更新但非最短路的元素{d[x],x}在堆中,
//而在后面的遍历中x距离被再次更新,{d[x]',x}入堆,
//此时堆中便同时存在一个点的两个元素,
//(可以证明在x再次被更新前,{d[x],x}不会弹出)
//而先入堆者距离一定更长,为冗余项,
//遇到了之后continue即可
//相当于Dijkstra II用x的再次入堆等效了Dijkstra I的对x直接更新
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int h[N], e[N], ne[N], w[N], idx, d[N], n, m;
bool st[N];
priority_queue<PII, vector<PII>, greater<PII>> heap;
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
void Dijkstra()
{
d[1] = 0;
heap.push({ 0,1 });
while (heap.size())
{
auto t = heap.top();
heap.pop();
int x = t.second;
if (st[x]) continue;
st[x] = 1;
for (int i = h[x]; i != -1; i = ne[i])
{
int nx = e[i];
if (d[nx] > d[x] + w[i])
{
d[nx] = d[x] + w[i];
heap.push({ d[nx],nx });
}
}
}
}
int main()
{
memset(h, -1, sizeof(h));
memset(d, 0x3f, sizeof(d));
cin >> n >> m;
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
Dijkstra();
if (d[n] == 0x3f3f3f3f) cout << -1;
else cout << d[n];
return 0;
}