原理:
1.每次从未标记的节点中选择距离出发最近的节点,标记,收录到最优路径的集合中
2.计算刚加入节点a的邻近节点b的距离,并根据条件更新节点b的距离
dijkstra堆优化版
#include<bits/stdc++.h>
using namespace std;
const int N = 3000, M = 20000;
typedef pair<int, int> PII;
int h[N], w[M], e[M], ne[M], idx;
bool ste[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++;
}
int dijkstra(int st, int ed)
{
int dist[M];
memset(dist, 0x3f, sizeof dist);
dist[st] = 0;
//ste[st] = true;
heap.push({ 0,st });
while (heap.size())
{
auto t = heap.top();
heap.pop();
//ste[t.second] = false;
//int distance=t.first,res=t.second;
for (int i = h[t.second]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] > t.first + w[i])
{
dist[j] = t.first + w[i];
heap.push({ dist[j],j });
}
}
}
return dist[ed];
}
int main()
{
int n, m, st, ed;
cin >> n >> m >> st >> ed;
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
add(a, b, w), add(b, a, w);
}
int t = dijkstra(st, ed);
cout << t << endl;
return 0;
}
//由于push_back的存在,时间比原来慢50%
#include<bits/stdc++.h>
using namespace std;
const int N = 3000, M = 20000;
typedef pair<int, int> PII;
priority_queue<PII, vector<PII>, greater<PII>> heap;
vector<int>e[N];
int w[M],to[M],cnt=0;
void add(int a, int b, int c){
w[cnt]=c,to[cnt]=b,e[a].push_back(cnt++);
}
int dijkstra(int st, int ed)
{
int dist[M];
memset(dist, 0x3f, sizeof dist);
dist[st] = 0;
heap.push({ 0,st });
while (heap.size())
{
auto t = heap.top();
heap.pop();
for (int i = 0; i<(int)e[t.second].size(); i++)
{
int h=e[t.second][i];
int j = to[h];
if (dist[j] > t.first + w[h])
{
dist[j] = t.first + w[h];
heap.push({ dist[j],j });
}
}
}
return dist[ed];
}
int main()
{
int n, m, st, ed;
cin >> n >> m >> st >> ed;
for (int i = 0; i < m; i++)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
add(a, b, w), add(b, a, w);
}
int t = dijkstra(st, ed);
cout << t << endl;
return 0;
}
dijkstra朴素版
#include<bits/stdc++.h>
using namespace std;
const int N = 3000;
int g[N][N], dist[N];
int n, m, s, e;
bool st[N];
int dijkstra(int s, int e)
{
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
for (int i = 1; i < n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++) if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j;
st[t] = true;
for (int j = 1; j <= n; j++) dist[j] = min(dist[j], dist[t] + g[t][j]);
}
return dist[e];
}
int main()
{
cin >> n >> m >> s >> e;
memset(g, 0x3f, sizeof g);
for (int i = 0; i < m; i++)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
g[a][b] = g[b][a] = min(g[a][b], w);
}
int t = dijkstra(s, e);
cout << t << endl;
return 0;
}