前言
本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。
Folyd实现原理
中心点的概念
感觉像是充当一个桥梁的作用
还是这个图
我们常在一些讲解视频中看到,就比如dist(-1),这是原始的邻接矩阵
dist(0),就是A充当中心点
这时候就是打比方,我D->E,A作为中心点之后,这一轮就是看D->A->E的距离相较之前是否最小,所以,A->A->B多次一举,所以pass,X->A->A也是多此一举,所以pass,对角线别动X->A->X又回到自己PASS。一来三个pass,差不多如图。我们只需要剩下的就可以。
打比方B->C,那么加入A之后就是B->A->C=BA+AC=8+1=9,相比于之前的6,大了,所以不换不更新。
B->E,那么加入A之后就是B->A->E,BA+AE=8+INF,直接pass遇到不通的情况。
遍历完B,到C继续重复步骤更新……即可,脑力有限,就不多解释了。
这样我每个点都充当一次中心点下来,我的最短路径也出来了。
Folyd实现代码
Folyd的代码形式十分简单,如果比赛中看寻找最短路径,嫌Dijkstra算法麻烦的话,直接试试Folyd看看能不能过,不能再说单源的。以下是主要实现代码。
public int[][] Folyd(){
int N = vertexList.size();
int[][] edges = new int[N][N];
//新开个二维数组,防止数据被动
//edges[i] = this.edges[i],这样是不行的,因为java的引用
for(int i = 0;i<N;i++){
for(int j=0;j<N;j++){
edges[i][j] = this.edges[i][j];
}
}
//弗洛伊德算法就是要求整个的
for(int k = 0;k<N;k++){//中心点
for(int i = 0;i<N;i++){//哪个点
//if(i==k) continue;
for(int j = 0;j<N;j++){//到哪个点
//if(j == k) continue;
if(i == j) continue;
if(edges[i][k] !=Integer.MAX_VALUE && edges[k][j] != Integer.MAX_VALUE){
edges[i][j] = Math.min(edges[i][j], edges[i][k] + edges[k][j]);
//当前的ij位置
}
}
}
}
return edges;
}
三层循环,代码中注释//掉的if就是我原理里面pass的东西。
以下是完整的实现代码,以及与迪杰斯特拉算法结果的比对。
//package GraphTest.Demo;
import java.util.*;
public class Graph{//这是一个图类
/***基础属性***/
int[][] edges; //邻接矩阵存储边
ArrayList<EData> to = new ArrayList<>(); //EData包含start,end,weight三个属性,相当于另一种存储方式,主要是为了实现kruskal算法定义的
ArrayList<String> vertexList = new ArrayList<>(); //存储结点名称,当然你若想用Integer也可以,这个是我自己复习用的
int numOfEdges; //边的个数
boolean[] isVisited;
//构造器
Graph(int n){
this.edges = new int[n][n];
//为了方便,决定讲结点初始化为INF,这也方便后续某些操作
int INF