标题：Floyd算法
核心思路
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
从图的带权邻接矩阵A=[a(i,j)] n×n开始，递归地进行n次更新，即由矩阵D(0)=A，按一个公式，构造出矩阵D(1)；又用同样地公式由D(1)构造出D(2)；……；最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度，称D(n)为图的距离矩阵，同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
采用的是(松弛技术)，对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);
其状态转移方程如下： map[i,j]:=min{map[i,k]+map[k,j],map[i,j]}
map[i,j]表示i到j的最短距离
K是穷举i,j的断点
map[n,n]初值应该为0，或者按照题目意思来做。
当然，如果这条路没有通的话，还必须特殊处理，比如没有map[i,k]这条路
算法过程
1，从任意一条单边路径开始。所有两点之间的距离是边的权，如果两点之间没有边相连，则权为无穷大。
2，对于每一对顶点 u 和 v，看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
===
把图用邻接距阵G表示出来，如果从Vi到Vj有路可达，则G[i,j]=d，d表示该路的长度；否则G[i,j]=无穷大。
定义一个距阵D用来记录所插入点的信息，D[i,j]表示从Vi到Vj需要经过的点，初始化D[i,j]=j。
把各个顶点插入图中，比较插点后的距离与原来的距离，G[i,j] = min( G[i,j], G[i,k]+G[k,j] )，如果G[i,j]的值变小，则D[i,j]=k。
在G中包含有两点之间最短道路的信息，而在D中则包含了最短通路径的信息。
比如，要寻找从V5到V1的路径。根据D，假如D(5,1)=3则说明从V5到V1经过V3，路径为{V5,V3,V1}，如果D(5,3)=3，说明V5与V3直接相连，如果D(3,1)=1，说明V3与V1直接相连。
时间复杂度
O(n^3)
优缺点分析
Floyd算法适用于APSP(All Pairs Shortest Paths)，是一种动态规划算法，稠密图效果最佳，边权可正可负。此算法简单有效，由于三重循环结构紧凑，对于稠密图，效率要高于执行|V|次Dijkstra算法。
优点：容易理解，可以算出任意两个节点之间的最短距离，代码编写简单
缺点：时间复杂度比较高，不适合计算大量数据。
概述
Floyd算法又称为弗洛伊德算法，插点法，是一种用于寻找给定的加权图中顶点间最短路径的算法。
算法描述
a)　初始化：D[u,v]=A[u,v]
b)　For k:=1 to n
For i:=1 to n
For j:=1 to n
If D[i,j]>D[i,k]+D[k,j] Then
D[I,j]:=D[I,k]+D[k,j];
c)　算法结束：D即为所有点对的最短路径矩阵
算法实现
C语言 
#include<stdio.h>
#define MAXV 100
#define INF 32767
#include "graph.h"
//extern void DispMat(MGraph g);
void DispMat(MGraph g)
{
int i,j;
for(i=0;i<g.n;i++)
{
for(j=0;j<g.n;j++)
if(g.edges[i][j]==INF)
printf("%3s","∞");
else
printf("%3d",g.edges[i][j]);
printf("\n");
}
}
void ppath(int path[][MAXV],int i,int j)
{
int k;
k=path[i][j];
if(k==-1) return;
ppath(path,i,k);
printf("%d,",k);
ppath(path,k,j);
}
void DisPath(int A[][MAXV],int path[][MAXV],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(A[i][j]==INF)
{
if(i!=j)
printf("从%d到%d没有路径");
}
else
{
if(i<j)
{
printf("从%d到%d的路径为:",i,j);
printf("%d,",i);
ppath(path,i,j);
printf("%d",j); 
printf("\t路径长度为：%d\n",A[i][j]);
}
}
}
void Floyd(MGraph g)
{
int A[MAXV][MAXV];
int path[MAXV][MAXV];
int i,j,k,n=g.n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
A[i][j]=g.edges[i][j];
path[i][j]=-1;
}
for(k=0;k<n;k++)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(A[i][j]>(A[i][k]+A[k][j]))
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
printf("\n输出最短路径：\n");
DisPath(A,path,n);
}
void main()
{
int i,j,u=0;
MGraph g;
double A[51][51];
for(i=0;i<51;i++)
{
for(j=0;j<51;j++)
{
A[i][j]=INF;
}
}
A[0][18]=2182.0;
A[0][21]=1796.9;
A[0][26]=1392.1;
A[1][3]=1916.3;
A[1][6]=1294.3;
A[1][7]=1968.2;
A[1][8]=2.8638e+003;
A[2][4]=2.2926e+003;
A[2][5]=1.2529e+003;
A[2][20]=7.8233e+003;
A[3][4]=3.5364e+003;
A[3][8]=1.9581e+003;
A[5][15]=5.0045e+003;
A[7][10]=2.0594e+003;
A[7][18]=5.9179e+003;
A[8][12]=1.7568e+003;
A[9][10]=1.9455e+003;
A[9][14]=2.6813e+003;
A[10][18]=5.9095e+003;
A[11][12]=1.4177e+003;
A[11][13]=1.6696e+003;
A[12][13]=1.4568e+003;
A[12][15]=4.8058e+003;
A[12][25]=5.7566e+003;
A[13][18]=3.1135e+003;
A[13][19]=3.4557e+003;
A[14][16]=2.6077e+003;
A[14][17]=2.1957e+003;
A[14][18]=5.3422e+003;
A[14][21]=3.2967e+003;
A[15][22]=2.8610e+003;
A[15][25]=4.2354e+003;
A[16][23]=2.0976e+003;
A[17][21]=1.8239e+003;
A[17][23]=1.7745e+003;
A[18][31]=2.1037e+003;
A[19][24]=2.2586e+003;
A[19][25]=1.9662e+003;
A[20][22]=1.4989e+003;
A[21][26]=2.1917e+003;
A[21][36]=2.8802e+003;
A[22][29]=1.0979e+003;
A[22][30]=1.2875e+003;
A[23][32]=1.3119e+003;
A[24][31]=1.7801e+003;
A[25][29]=1.8859e+003;
A[25][41]=4.1546e+003;
A[26][31]=1.5370e+003;
A[27][31]=1.0678e+003;
A[27][36]=2.2039e+003;
A[27][39]=1.7799e+003;
A[28][30]=1.0179e+003;
A[28][33]=1.3257e+003;
A[30][41]=4.9976e+003;
A[31][34]=2.3247e+003;
A[32][35]=1.1140e+003;
A[33][46]=3.7585e+003;
A[34][40]=1.6308e+003;
A[35][38]=1.4097e+003;
A[36][38]=1.5374e+003;
A[36][45]=3.1825e+003;
A[37][40]=2.0901e+003;
A[37][41]=2.6019e+003;
A[38][43]=2.6184e+003;
A[40][45]=3.2170e+003;
A[40][47]=2.3312e+003;
A[40][50]=3.0435e+003;
A[41][44]=2.3660e+003;
A[41][46]=2.7354e+003;
A[42][43]=917.6737;
A[42][45]=2.3517e+003;
A[42][49]=1.9714e+003;
A[44][48]=2.1525e+003;
A[44][50]=4.9870e+003;
A[45][50]=3.1028e+003;
A[46][48]=1.4941e+003;
A[49][50]=3.5688e+003;
for(i=0;i<51;i++)
{
for(j=0;j<51;j++)
{
if(A[i][j]!=0) 
A[j][i]=A[i][j];
}
}
g.n=51;
g.e=154;
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
g.edges[i][j]=A[i][j];
printf("\n");
printf("图G的邻接矩阵：\n");
DispMat(g);
Floyd(g);
printf("\n");
}
C++语言 
#include<fstream>
#define Maxm 501
using namespace std;
ifstream fin;
ofstream fout("APSP.out");
int p,q,k,m;
int Vertex,Line[Maxm];
int Path[Maxm][Maxm],Dist[Maxm][Maxm];
void Root(int p,int q)
{
if (Path[p][q]>0)
{
Root(p,Path[p][q]);
Root(Path[p][q],q);
}
else 
{
Line[k]=q;
k++;
}
}
int main()
{
memset(Path,0,sizeof(Path));
memset(Dist,0,sizeof(Dist));
fin >> Vertex;
for(p=1;p<=Vertex;p++)
for(q=1;q<=Vertex;q++)
fin >> Dist[p][q];
for(k=1;k<=Vertex;k++)
for(p=1;p<=Vertex;p++)
if (Dist[p][k]>0)
for(q=1;q<=Vertex;q++)
if (Dist[k][q]>0)
{
if (((Dist[p][q]>Dist[p][k]+Dist[k][q])||(Dist[p][q]==0))&&(p!=q))
{
Dist[p][q]=Dist[p][k]+Dist[k][q];
Path[p][q]=k;
}
}
for(p=1;p<=Vertex;p++)
{
for(q=p+1;q<=Vertex;q++)
{
fout << "\n==========================\n"; 
fout << "Source:" << p << '\n' << "Target " << q << '\n'; 
fout << "Distance:" << Dist[p][q] << '\n';
fout << "Path:" << p;
k=2;
Root(p,q);
for(m=2;m<=k-1;m++)
fout << "-->" << Line[m];
fout << '\n';
fout << "==========================\n";
}
}
fin.close();
fout.close();
return 0;
}
注解：无法连通的两个点之间距离为0;
Sample Input
7
00 20 50 30 00 00 00
20 00 25 00 00 70 00
50 25 00 40 25 50 00
30 00 40 00 55 00 00
00 00 25 55 00 10 70
00 70 50 00 10 00 50
00 00 00 00 70 50 00
Sample Output
==========================
Source:1
Target 2
Distance:20
Path:1-->2
==========================
==========================
Source:1
Target 3
Distance:45
Path:1-->2-->3
==========================
==========================
Source:1
Target 4
Distance:30
Path:1-->4
==========================
==========================
Source:1
Target 5
Distance:70
Path:1-->2-->3-->5
==========================
==========================
Source:1
Target 6
Distance:80
Path:1-->2-->3-->5-->6
==========================
==========================
Source:1
Target 7
Distance:130
Path:1-->2-->3-->5-->6-->7
==========================
==========================
Source:2
Target 3
Distance:25
Path:2-->3
==========================
==========================
Source:2
Target 4
Distance:50
Path:2-->1-->4
==========================
==========================
Source:2
Target 5
Distance:50
Path:2-->3-->5
==========================
==========================
Source:2
Target 6
Distance:60
Path:2-->3-->5-->6
==========================
==========================
Source:2
Target 7
Distance:110
Path:2-->3-->5-->6-->7
==========================
==========================
Source:3
Target 4
Distance:40
Path:3-->4
==========================
==========================
Source:3
Target 5
Distance:25
Path:3-->5
==========================
==========================
Source:3
Target 6
Distance:35
Path:3-->5-->6
==========================
==========================
Source:3
Target 7
Distance:85
Path:3-->5-->6-->7
==========================
==========================
Source:4
Target 5
Distance:55
Path:4-->5
==========================
==========================
Source:4
Target 6
Distance:65
Path:4-->5-->6
==========================
==========================
Source:4
Target 7
Distance:115
Path:4-->5-->6-->7
==========================
==========================
Source:5
Target 6
Distance:10
Path:5-->6
==========================
==========================
Source:5
Target 7
Distance:60
Path:5-->6-->7
==========================
==========================
Source:6
Target 7
Distance:50
Path:6-->7
==========================Matlab源代码为