算法思路:
记录1号点到每个点的最短距离dist【N】,每次寻找到距离最小的点,利用它去更新还没确定最短路的其他点。
朴素Dijktsra{ O(n^2+m) }
int g[N][N] //存储边
int dist[N] //存储最短距离
bool st[N] //判断每个点的最短路是否被确定
//求1号点到n号点的最短路,如果没有返回-1
int dijkstra()
{
memser(dist,0x3f,sizeof dist); //初始化距离为无穷大
dist[1]=0; //1号点到1号点的距离就是0
for(int i=0;i<n-1;i++)
{
int t = -1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
//利用t去更新其他未确定最短路的结点
for(int j=1;j<=n;j++)
dist[j=min(dist[j],dist[t]+g[t][j]);
st[t]=true; //该点的最短路已确定
}
if(dist[n] ==0x3f3f3f3f) return -1;
return dist[n];
}
堆优化版dijkstra
using namespace std;
const int N =1010;
typedef pair<int ,int>PII;
int n; //点的数量
int h[N],w[N],e[N],ne[N],idx; //邻接表存储
int dist[N] //储存最短距离
bool st[N] //判断最短距离是否已经确定
//求1号点到n号点的最短距离,如果不存在,则返回-1
int dijkstra()
{
memset(dist , ox3f,sizeof dist) //初始化距离为无穷大
dist[1]=0; //1号点到1号点的距离为0
priority_queue<PII,vector<PII>,greater<PII> > heap; //小根堆的定义模板
heap.push({0,1}); //插入距离和结点的编号
while(heap.size()) //不空
{
auto t =heap.top(); //取堆顶元素,因为是小根堆,必然是距离原点最近的一个点
heap.pop();
int ver=t.second,distance=t.first //保存结点编号以及距离
if(st[ver]) continue; //距离已经确定 则跳过
st[ver] = true;
for(int i=h[ver];i!=-1;i=ne[i]) //邻接矩阵遍历模板
{
int j =e[i];
if(dist[i]>dist[ver]+w[i])
{
dist[j]=dist[ver]+w[i];
heap.push({dist[j],j}); //距离小则入堆
}
}
}
if(dist[n]==0x3f3f3f3f) return -1;
return dist[n];
}