弗洛伊德算法(Floyd),又称为是插点法。目的是求加权图中顶点中最短路径的方法。本文通过举例子的方法想你具体解释何为弗洛伊德算法。
有一个送礼物的问题,是CSDN上的一个题目,题目的详情是这样的。
题目详情:
HeHe和XiXi在一个地方玩游戏,XiXi把N-1件礼物(HeHe以前送给XiXi的)分别藏在了另外N-1个地方,这些地方都能互相到达,且所有的边都是有方向的。
现在HeHe要做的事就是去那些地方找回那N-1件礼物给XiXi;
由于每一件礼物都有特殊的意义,所以XiXi要求HeHe每找到一件礼物,就必须马上返回XiXi所在的位置,对她说一句当年送她这件礼物的时候所说的话。
由于每走一个单位长度HeHe需要花费1分钟,XiXi还要求HeHe在最快的时间内把这些礼物带回来交给她,你能帮助HeHe么?
输入
测试数据有T组,每组测试数据开始为两个整数N和M,1 <= N,M <= 100000。
N代表所有的位置,M代表这些位置之间的长度
然后是M行,每行有三个数,u,v,w,即位置u和位置v之间有一条单向的边,距离为w;
你可以假设位置的编号是从1到N,XiXi的位置始终都在1;
输出
对于每组测试数据, 用一行输出HeHe所花费的最短时间。
答题说明:
输入样例
1
3 3
1 2 4
2 3 5
3 1 6
输出样例
30
可知道,题目需要求得的是:D[1→2]+D[2→1]+D[1→3]+D[3→1]的大小(D[i→j]表示结点i到j的最短距离):4+(5+6)+(4+5)+6=30
最后根据弗洛伊德算法思想写出来代码了,但是在CSDN运行时会出错。不过思想是没错的,大家可以根据代码理解下弗洛伊德
#include <stdio.h>
#include <string.h>
#define MAX 10000
int graph[1000][1000],g[1000][1000];//graph是各个节点之间距离,g代表邻接矩阵数组
int main()
{
int T,N,M;
int u,v,w;
int i,j,k;
int sum;
scanf("%d",&T);
while(T--)
{
memset(g,MAX,sizeof(g));
memset(graph,0,sizeof(graph));
sum=0;
scanf("%d%d",&N,&M);
for(i=0;i<N;i++)
{
g[i][i]=0; //令邻接矩阵对角线为0,因为结点i到结点i之间的距离为0
}
for(i=0;i<M;i++)
{
scanf("%d%d%d",&u,&v,&w);
g[u-1][v-1]=w; //把各个结点输入并且放入到邻接矩阵中
}
for(k = 0;k<N;k++)
for(i = 0;i<N;i++)
{
for(j = 0;j<N;j++)
{
if(k == 0)
{
graph[i][j] =g[i][j]; //首先,当k=0的时候,就是中间结点为结点1的时候,先把graph
}
else
{
if(graph[i][j]>(graph[i][k]+graph[k][j])) //如果D[i→k]+D[k→j]比起D[i→j]小,则可以在i,j中间插点形成最短
graph[i][j]=graph[i][k]+graph[k][j];
}
}
}
for(i=1;i<N;i++)
{
sum+=graph[0][i]+graph[i][0];
}
printf("%d\n",sum);
}
return 0;
}