数据结构:邻接表Map
空间复杂度 n^2
时间复杂度 n^2
算法功能:求一点到其他点的最短路径,不能有负边
算法思想:其实这个是有点类似于最小生成树的思想的
首先初始化,比如我要从节点1出发,那么我把ans数组先初始化为1到各个节点直接连接的距离,不能连接的话就为inf
然后就开始正片了,每一次循环我们都会将一个没有连到一起的点连进去因为一共有num个点所以要num-1个循环,但为了方便起见还是num个循环
大不了就多跑一个空循环嘛
每一次循环中我们都要找出未访问的节点中里已访问的节点最近的一个
然后将它标记为已访问,并通过这个点对剩下的ans进行重置(比较原来的路径与经过此点的路径并取最小值)其实是将v的邻接节点进行重置
因为只有这些节点受v影响后可以一直连到st节点
循环进行完后ans【n】就是st到n的最短路了
算法证明:若k不能连到st节点则ans【k】=inf,如果。。。。。等等,我TMD不会证。嘤嘤嘤
看今晚通识课能不能看懂网上的证明
算法代码即注释:
int Dijkstra(int st,int en,int Map[maxn][maxn],int num)//注意,如果maxn特别大则要将这个数组开到main函数外面
{
bool Vis[maxn];
int ans[maxn];
memset(Vis,0,sizeof(Vis));
Vis[st]=1;
for (int k=1;k<=num;k++)
ans[k]=Map[st][k];//以start节点开始,进行初始化
for (int k=0;k<num;k++)//一共要计算k次,每计算一次,一个节点被访问
{
int Min=inf,v;
for (int j=1;j<=num;j++) //找出未访问的节点中里已访问的节点最近的一个
if (!Vis[j]&&ans[j]<Min)
{Min=ans[j];v=j;}
Vis[v]=1;
for (int j=1;j<=num;j++) //因为这个节点已访问所以要把ans数组重置一遍其实是将v的邻接节点进行重置
if (ans[j]>ans[v]+Map[v][j])
ans[j]=ans[v]+Map[v][j];
}
return ans[en];
}