1)朴素Dijkstra算法
适用稠密图(m~n^2), 用邻接矩阵实现;
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1000;
int g[N][N];
int dis[N];
bool st[N];
int Dijkstra(int n )
{
memset(dis, inf, sizeof(dis));
dis[1] = 0 ;
for(int i =1; i<=n; i++)
{
int t = - 1;
for(int j = 1; j<= n; j++)
if(!st[j] && (t==-1 || dis[j] < dis[t]))
t = j;
st[t] = true;
for(int j = 1; j<= n; j++)
dis[j] = min(dis[j], dis[t] + g[t][j]);
}
if(dis[n] == inf) return -1;
return dis[n];
}
int main()
{
memset(g, inf, sizeof(g));
int n , m;
cin>>n>>m;
while( m -- )
{
int a, b, c;
cin>>a>>b>>c;
g[a][b] = min(g[a][b], c);
}
cout<<Dijkstra(n)<<endl;
return 0 ;
}
2)堆优化Dijkstra算法
适用稀疏图(n~m),用邻接表, 手写堆或者 优先队列(最小堆)实现;
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 150010;
typedef pair<int, int> PII;
int h[N], e[N], ne[N], in, w[N];
int dis[N];
bool st[N];
void add(int a, int b, int c)
{
w[in] = c;
e[in] = b;
ne[in] = h[a];
h[a] = in;
in++;
}
int Dijkstra(int n)
{
memset(dis, inf, sizeof(dis));
dis[1] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap;//只知道距离不够,还需记录端点以相互区别;
heap.push(make_pair(0, 1)); //相当于把dis[1] = 0扔进去
while(heap.size())//similar to bfs, pop出最小的
{
PII x = heap.top();
heap.pop();
int verx = x.second, dist = x.first;
if(st[verx]) continue;
st[verx] = true;
for(int i =h[verx]; i != -1; i = ne[i])
{
int j = e[i];
if(dis[j] > dist + w[i])
{
dis[j] = dist + w[i];
heap.push(make_pair(dis[j], j));
}
}
}
if(dis[n] == inf) return -1;
return dis[n];
}
int main()
{
int n, m ;
cin>>n>>m;
memset(h, -1, sizeof(h));
while(m --)
{
int a, b , c;
cin>>a>>b>>c;
add(a, b, c);
}
cout<<Dijkstra(n)<<endl;
return 0;
}