最短路学习笔记:Floyd&&Dijkstra
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路学习笔记:Floyd&&Dijkstra相关的知识,希望对你有一定的参考价值。
谨以此笔记记录jjw高三党四个月学习NOI的历程..如转载请标记出处
Floyd算法:
默认是业界最短路最简单的写法,并且只有五行。时间复杂度为O(N3),空间复杂度为O(N2)。
1 for(int k=1;k<=n;k++){ 2 for(int i=1;i<=n;i++){ 3 for(int j=1;j<=n;j++){ 4 if(f[i][j]>f[i][k]+f[k][j]){ 5 f[i][j]=f[i][k]+f[k][j]; 6 } 7 } 8 } 9 }
简单来说就是通过另一个点个点来收缩一个点到一个点的距离,如果f[i][j]>f[i][k]+f[k][j]的话就把f[i][j]变成f[i][k]+f[k][j]
emm...再简单的一个例子就是(1,2)=10,但是(1,3)+(3,2)=5,那么就可以通过点3把(1,2)的距离变为5。
还是很简单的吧...
Dijkstra算法:
刚刚的Floyd能够通过空间复杂度为On3的方法算出所有点到所有点的最短路,但是这样做在某些题目中会炸掉或者T掉,那么怎么解决单源最短路径?
(其实所有的最短路径都可以从啊哈磊先生的啊哈算法中找到详细讲解)
在我理解下的Dijkstra分为以下几个部分:
1、在二维图中标记已知路径,将位置路径设为inf
1 for(int i=1;i<=n;i++){ 2 for(int j=1;j<=n;j++){ 3 if(i==j){ 4 a[i][j]=0; 5 }else{ 6 a[i][j]=inf; 7 } 8 } 9 }
//inf一般为0xf 10 for(int i=1;i<=m;i++){ 11 int v,r,w; 12 scanf("%d%d%d",&v,&r,&w); 13 if(a[v][r]>w){ 14 a[v][r]=w; 15 }//这里一定要注意是否为有向边还是无向 16 17 }
2、数组dis和数组book
1 for(int i=1;i<=n;i++){ 2 f[i]=a[1][i]; 3 } 4 b[1]=1;
3、主要算法:
1 for(int i=1;i<=n;i++){ 2 int minx=inf,u=0; 3 for(int j=1;j<=n;j++){ 4 if(!b[j]&&f[j]<minx){ 5 minx=f[j]; 6 u=j; 7 } 8 } 9 b[u]=1; 10 for(int j=1;j<=n;j++){ 11 if(!b[j]){ 12 if(f[j]>f[u]+a[u][j]){ 13 f[j]=f[u]+a[u][j]; 14 } 15 } 16 } 17 }
解释以下:book数组用来记录松弛每个边,然后在循环每一个点中依次松弛从这个点到其他最小一个点的路径长短,比如前7行就是在找距离1号最短距离的X号,然后对X号松弛
第九行将准备松弛的点固定,然后松弛其它边。
应该是比较难理解的..不过多做几道题就差不多会写了。
题目:洛谷1576,2384
以上是关于最短路学习笔记:Floyd&&Dijkstra的主要内容,如果未能解决你的问题,请参考以下文章