【图】最短路径Floyd算法C语言实现

相关blog:【图】最短路径Dijkstra算法C语言实现

1.算法过程:

1.把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则 G [ i ] [ j ] = d G[i][j]=d G[i][j]=d d d d表示该路的长度;否则 G [ i ] [ j ] = ∞ G[i][j]=∞ G[i][j]=。一个点到自己的距离如 G [ i ] [ i ] = 0 G[i][i]=0 G[i][i]=0

2.定义一个矩阵D用来记录所插入点的信息, D [ i ] [ j ] D[i][j] D[i][j]表示从 V i Vi Vi V j Vj Vj需要经过的点,初始化 D [ i ] [ j ] = − 1 D[i][j]=-1 D[i][j]=1
3.把各个顶点插入图中,比较插点后的距离与原来的距离, G [ i ] [ j ] = m i n ( G [ i ] [ j ] , G [ i ] [ k ] + G [ k ] [ j ] ) G[i][j] = min( G[i][j], G[i][k]+G[k][j] ) G[i][j]=min(G[i][j],G[i][k]+G[k][j]),如果 G [ i ] [ j ] G[i][j] G[i][j]的值变小,则 D [ i ] [ j ] = k D[i][j]=k D[i][j]=k(记录中间结点)。在 G G G中包含有两点之间最短道路的信息,而在 D D D中则包含了最短通路径的信息。

比如,要寻找从V5到V1的路径。根据D,假如 D ( 5 , 1 ) = 3 D(5,1)=3 D(5,1)=3则说明从V5到V1经过V3,路径为 V 5 , V 3 , V 1 {V5,V3,V1} V5,V3,V1,如果 D ( 5 , 3 ) = 3 D(5,3)=3 D(5,3)=3,说明V5与V3直接相连,如果 D ( 3 , 1 ) = 1 D(3,1)=1 D(3,1)=1,说明V3与V1直接相连。

4. D D D即为所有点对的最短路径矩阵

5.得到最短路径矩阵后,若 p a t h [ i ] [ j ] = − 1 path[i][j]=-1 path[i][j]=1,表示此路通,可以直接输出,否则, i , j i,j i,j不直接相通,第一个中间结点 m i d = p a t h [ i ] [ j ] mid=path[i][j] mid=path[i][j],继续将 p a t h [ i ] [ m i d ] path[i][mid] path[i][mid] p a t h [ m i d ] [ j ] path[mid][j] path[mid][j]递归求解.

2.代码:

#include<stdio.h>
  
#define SIZE 110  
#define INF 1000000

int sum=0;
 
void Floyd(int n,int Graph[][SIZE],int path[][SIZE])//求最短路径矩阵path[][]
{ 
    int i,j,k;
    int A[SIZE][SIZE];
    for(i = 0;i < n;i++)
    {
        for(j = 0;j < n;j++)
        {
            A[i][j] = Graph[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;
                 }
            }
        }
    }
}
int  gen(int map[SIZE][SIZE],int start ,int end)//图的建立
{
    int vertex;
    int i,j;
    int k;
    int Ver;
    int edge_num;

    scanf("%d%d",&vertex,&edge_num);
    
    for(i=0;i<=vertex;i++)
    {
        for(j=0;j<=vertex;j++)
        if(i == j)
        {
            map[i][j] = 0;
        }
        else
        {
            map[i][j] = INF;
        }
    }

    for(k=0;k<edge_num;k++)
    {
        scanf("%d%d",&i,&j);
        scanf("%d",&map[i][j]);
        //map[j][i]=map[i][j];
    }

     return vertex;//返回顶点数目
} 
void shortpath(int start,int end,int path[][SIZE],int Graph[][SIZE])//打印最短路径
{
    if(path[start][end] == -1)
    {
        printf("<%d,%d>",start,end);
        sum = sum+Graph[start][end];
    }

    else
    {
        int mid = path[start][end];
        shortpath(start,mid,path,Graph);
        shortpath(mid,end,path,Graph);
    }
    
}
int main () {  
 
   int Graph[SIZE][SIZE];
   int path[SIZE][SIZE];

   int start,end;
   scanf("%d%d",&start,&end);//记录出发点和目的地

   int vertexnum = gen(Graph,start,end);
   Floyd(vertexnum,Graph,path);
   shortpath(start,end,path,Graph);
   printf("\n%d",sum);
 
    return 0;  
}

3.测试:

输入:

1 0//从1到0的最短路径
4 8//四个顶点八条边
0 1 5
0 3 7
1 2 4
1 3 2
2 0 3
2 1 3
2 3 2
3 2 1

输入的后8行相当于

    map[0][1] = 5;	//测试数据 
	map[0][3] = 7;
	map[1][2] = 4;
	map[1][3] = 2;
	map[2][0] = 3;
	map[2][1] = 3;
	map[2][3] = 2;
	map[3][2] = 1;

输出:

<1,3><3,2><2,0>//轨迹
6             //最短路径

相关blog:【图】最短路径Dijkstra算法C语言实现

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值