–
前言
如果你对图论相关知识一点也没有,那么建议您先去了解这些知识:
讲解视频1
讲解视频2
画图工具
算法思想
队列优化,去掉一些无用的松弛操作,用队列来维护松弛造作的点。继承了Bellman-Ford算法的思想,但时间复杂度相对来说提高了很多。
与BFS的算法有一些类似,利用了STL队列。
时间复杂度
理想复杂度为O ( K M ) O(KM)O(KM),这里的K KK可以看作一个常数
最坏为O ( N M ) O(NM)O(NM)但是一般情况下是跑不到这么多(除非出题人卡SPFA)
注意
虽然大多数情况spfa跑的比较快,但时间复杂度仍为(Onm),主要用应用于有负边权的情况(如果没有负边权,推荐使用 Dijkstra算法)。利用了邻接表建图,数据结构的基础一定要掌握好,而且该算法很容易超时,被卡,必须要谨慎选择该算法。
算法分析
1.用dis数组记录点到有向图的任意一点距离,初始化起点距离为0,其余点均为INF,起点入队。
2.判断该点是否存在。(未存在就入队,标记)
3.队首出队,并将该点标记为没有访问过,方便下次入队。
4.遍历以对首为起点的有向边(t,i),如果dis[i]>dis[t]+w(t,i),则更新dis[i]。
5.如果i不在队列中,则入队标记,一直到循环为空。
例题(模板)
题目:求一个无向图的最短路径(dijkstra)
题目描述
一个含n个结点的无向图,以矩阵存储方式给出,请求出指定的两个点之间的最短距离。
输入输出格式
输入格式:
第一行,一个整数n(0 < n < 1000 ),表示无向图中结点的个数。
接下来是一个n*n的矩阵,表示无向图中各结点之间的联结情况,矩阵中的数值为小于等于1000的下整数,其中 0 表示两点之间无直接连接。
最后一行,两个整数i,j。表示求解i点到j点的最短距离。
输出格式:
一个数值,表示指定的两点之间最短距离。
输入输出样例
输入样例:
2
0 2
2 0
1 2
输出样例:
2
Code
#include<iostream>
#include<cstdio>
using namespace std;
long long n,m,x,y,s,t,i,j,a[1100][1100],b[1100],c[1100];
int main()
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%lld",&a[i][j]);
if(!a[i][j])
a[i][j]=10000;
}
scanf("%lld%lld",&x,&y);
c[x]=1;
for(i=1;i<=n;i++)
b[i]=a[x][i];
for(i=1;i<=n;i++)
{
s=1;
t=10000;
for(j=1;j<=n;j++)
if(!c[j]&&t>b[j])
{
s=j;
t=b[j];
}
c[s]=1;
for(j=1;j<=n;j++)
if(!c[j]&&b[s]+a[s][j]<b[j])
b[j]=b[s]+a[s][j];
}
printf("%lld",b[y]);
return 0;
}
以上就是本文的内容,请在评论区提出您宝贵的意见,谢谢!