dijkstr算法用来求图中每个点到起点的最短距离。
具体方法是,我们刚开始把除了1号点到起点的距离为1外,其他点到起点的距离都初始化为正无穷:
然后经过n次迭代,每次都把从距离起点最近的点推。现在1节点到起点的距离是0,2节点到起点的距离是1,3节点到起点的距离是4。表示如下:
我们接着推,2节点到3节点的距离是2,又因为2节点到1节点的距离是1,因此3节点到1节点的距离是3这条路径比3节点到1节点是4这条路径更短,节点3到起点的最短距离更新为节点2到起点的距离+节点3到节点2的距离=3
稠密图 邻接矩阵
849. Dijkstra求最短路 I - AcWing题库
n是500,m是1e5,总共就有500*1e5个点边,比较稠密,用邻接矩阵。
//稠密图 邻接矩阵
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=510;
int g[N][N]; //邻接矩阵
bool st[N]; //每个点的最短距离是否已经确定
int dist[N]; //每个点到起点的距离
int dijkstr()
{
//初始化距离数组 因为求最短距离,所以要初始化为最大值
memset(dist,0x3f,sizeof dist);
dist[1]=0; //1号节点到起始点的距离是0
//迭代n次
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!st[j]&&(t==-1||dist[t]>dist[j])) //如果t没有被确定为最近的路并且t不是最短的路
t=j; //更新t为j //更新
}
st[t]=true; //加入st里,表示t这条边已经确定为最短边
for(int j=1;j<=n;j++)
{
dist[j]=min(dist[j],dist[t]+g[t][j]); //更新一下1到j节点的最短距离
}
}
//如果dist还是最大值说明不存在一条最短路,返回-1即可
if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
}
int main()
{
memset(g,0x3f,sizeof g); //邻接矩阵初始化
cin>>n>>m;
while(m--)
{
int a,b,c;cin>>a>>b>>c;
g[a][b]=min(g[a][b],c); //多条边里取较短的那条
}
int t=dijkstr();
cout<<t<<endl;
return 0;
}
堆优化 邻接表
850. Dijkstra求最短路 II - AcWing题库
//稠密图 邻接矩阵
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef pair<int,int>PII;
int n,m;
int h[N],e[N],ne[N],w[N],dist[N],idx;
bool st[N];
void add(int a,int b,int c)
{
e[idx]=b; //把b赋给边值e
w[idx]=c; //把距离给w
ne[idx]=h[a]; //头节点指针下一个指针
h[a]=idx++; //头节点移到下一个节点
}
int dijkstr()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,1}); //放入节点1,距离起点为0
while(heap.size())
{
auto t=heap.top(); //每次取出距离分短的边
heap.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue; //如果当前节点之前走过,说明冗余了,不用再处理当前节点
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>distance+w[i])
{
dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}st[ver] = true;
}
if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
}
int main()
{
cin>>n>>m;
//memset(dis,INF,sizeof dis);
memset(h,-1,sizeof h); //初始化邻接表
//读入m条边
while(m--)
{
int x,y,z;cin>>x>>y>>z;
add(x,y,z);
}
int t=dijkstr();
cout<<t<<endl;
return 0;
}