Dijkstra
无负权边图中的最短路
维护一个顶点集合C,满足对于所有集合C的顶点x,我们都已经找到起点到x的最短路,此时dist(x)记录的就是最终最短路的长度。
将C设置为空,将S的距离为0,其余顶点的距离设置为无穷大。
在每一轮中,将离起点最近的(dist最小)的还不在C中的顶点加入C,并且用这个点连出去的边通过松弛操作尝试更新其他点的dist。
当T加入C时或者没有新的点加入C时结束。
时间复杂度 O ( n 2 + m ) O(n^2+m) O(n2+m)
邻接表
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
vector<PII> edge[N];
int n, m, dist[N];
bool b[N];
int Dijkstra(int s, int t)
{
memset(b, false, sizeof b);
memset(dist, 127, sizeof dist);
dist[s] = 0;
while (true)
{
int x = -1;
for (int i = 1; i <= n; i++)
if (!b[i] && dist[i] < 1 << 30)
if (x == -1 || dist[i] < dist[x])
x = i;
if (x == t || x == -1)
break;
b[x] = true;
for (auto i : edge[x])
dist[i.first] = min(dist[i.first], dist[x] + i.second);
}
if (dist[t] < 1 << 30)
return dist[t];
else
return -1;
}
邻接矩阵
int g[N][N];
int dist[N];
bool st[N];
int dijkstra(int s, int t)
{
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
for (int i = 0; i < n - 1; i++)
{
int x = -1;
for (int j = 1; j <= n; j++)
if (!st[j] && (x == -1 || dist[x] > dist[j]))
x = j;
for (int j = 1; j <= n; j++)
dist[j] = min(dist[j], dist[x] + g[x][j]);
st[x] = true;
}
if (dist[t] == 0x3f3f3f3f)
return -1;
return dist[t];
}
Dijkstra优化
set优化
时间复杂度: O ( ( n + m ) l o g n ) O((n+m)log n) O((n+m)logn)
typedef pair<int, int> PII;
const int N = 5e3 + 10;
const int M = 1e4 + 10;
set<PII> q;
vector<PII> edge[N];
int n, m, dist[N];
int Dijkstra(int s, int t)
{
memset(dist, 127, sizeof dist);
dist[s] = 0;
q.clear();
for (int i = 1; i <= n; i++)
q.insert({dist[i], i});
while (!q.empty())
{
int x = q.begin()->second;
q.erase(q.begin());
if (x == t || dist[x] > 1 << 30)
break;
for (auto i : edge[x])
{
if (dist[x] + i.second < dist[i.first])
{
q.erase({dist[i.first], i.first});
dist[i.first] = dist[x] + i.second;
q.insert({dist[i.first], i.first});
}
}
}
if (dist[t] < 1 << 30)
return dist[t];
else
return -1;
}
priority_queue优化
时间复杂度: O ( m l o g n ) O(mlog n) O(mlogn)
typedef pair<int, int> PII;
vector<PII> edge[N];
int dist[N];
bool st[N];
int Dijkstra(int s, int t)
{
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
dist[s] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, s});
while (heap.size())
{
auto t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
if (st[ver])
continue;
st[ver] = true;
for (auto i : edge[ver])
{
if (dist[i.first] > distance + i.second)
{
dist[i.first] = distance + i.second;
heap.push({dist[i.first], i.first});
}
}
}
if (dist[t] == 0x3f3f3f3f)
return -1;
return dist[t];
}