19 Froyd-Warshall算法

        Froyd-Warshall算法用于求解所有点对之间的最短距离,其中权值可以为负值,但是不能有负数的环。时间复杂度为O(n^3)。

        该算法的思路是,

        第一步:所有从 i 到 j 的最短路径为i、j之间的权值(不相连的话就设为某个MAX数值)

        第二步:如果结点数为 n, 对 n 从 1 到 n,每次假设加入一个结点后,那么 i 与 j之间的最短距离要么还是原来的值,要么是新结点加入后,通过新结点的“新”最短路径修正的值。即状态转移方程为:

        其中上标 k 表示最短路径经过的结点属于集合{1,2,3,...,k}

 

#include <iostream>
#include <string>   
#include <stdio.h>   
using namespace std;   
#define MaxVertexNum 100   
#define INF 10000   
typedef struct  
{   
    char vertex[MaxVertexNum];   
    int edges[MaxVertexNum][MaxVertexNum];   
    int n,e;   
}MGraph;   
 
void CreateMGraph(MGraph &G)   
{   
    int i,j,k,p;   
    cout<<"请输入顶点数和边数:"<<endl;   
    cin>>G.n>>G.e;   
    cout<<"请输入顶点元素:"<<endl;			//用A、B、C等来表示顶点   
    for (i=0;i<G.n;i++)   
    {   
        cin>>G.vertex[i];   
    }   
    for (i=0;i<G.n;i++)   
    {   
        for (j=0;j<G.n;j++)   
        {   
            G.edges[i][j]=INF;   
            if (i==j)   
            {   
                G.edges[i][j]=0;   
            }   
        }   
    }      
    for (k=0;k<G.e;k++)   
    {   
        cout<<"请输入第"<<k+1<<"条边的首尾顶点和相应的权值:"<<endl;   
        cin>>i>>j>>p;   
        G.edges[i][j]=p;   
    }   
}   
void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n);
 
void Floyd(MGraph G)
{
	int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum];
	int i,j,k;
	for (i=0;i<G.n;i++)
	{
		for (j=0;j<G.n;j++)
		{
			A[i][j]=G.edges[i][j];
			path[i][j]=-1;			//如果没有中间结点,则path[i][j]=-1
		}
	}
	for (k=0;k<G.n;k++)
	{
		for (i=0;i<G.n;i++)
		{
			for (j=0;j<G.n;j++)
			{
				if (A[i][j]>A[i][k]+A[k][j])
				//如果INF被定义为INT_MAX的话,要注意加法不要溢出
				{
					A[i][j]=A[i][k]+A[k][j];
					path[i][j]=k;	
					//注意,k记录的是最短路径中顶点标号最大的那个数,因此在下面的Ppah函数中要分别递归
				}
			}
		}
	}
	Dispath(A,path,G.n);
}
 
void Ppath(int path[][MaxVertexNum],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[][MaxVertexNum],int path[][MaxVertexNum],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没有路径\n",i,j);
				}
			}
			else
			{
				printf("  从%d到%d=>路径长度:%d路径:",i,j,A[i][j]);
				printf("%d,",i);
				Ppath(path,i,j);
				printf("%d\n",j);
			}
		}
	}
}
 
int main()
{
	/*freopen("input.txt", "r", stdin);*/
	MGraph G;
	CreateMGraph(G);
	Floyd(G);
	return 0;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值