Floyd算法

/*path应该怎么更新*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

#define INFINITY 999
typedef struct GNode* PtrToGNode;
typedef struct ENode* PtrToENode;

typedef int Vertex;
typedef int WeightType;
typedef char DataType;
struct GNode {
	int Nv;
	int Ne;
	WeightType** G;//二维矩阵,元素为边的权重,若为无向图则权重为1
	DataType* Data;
};
struct ENode {				//每一条边都对应一个结构
	Vertex V1, V2;
	WeightType weight;

};
typedef PtrToENode Edge;
typedef PtrToGNode MyGraph;
MyGraph CreateGraph(int VertexNum);
MyGraph Build_Graph();
typedef int Position;
typedef int ElementType;
typedef struct SNode* PtrToSNode;
struct SNode {
	ElementType* Data;
	Position Top;
	int MaxSize;
};
void Floyd(MyGraph Graph, int** Distance, int** Path);
void Read_Path(int** Path, int a, int b);
void Read_Path0(int** Path, int a, int b);

int main()
{


	MyGraph a = Build_Graph();
	int** Distance = (int**)malloc(sizeof(int*) * a->Nv);
	int** Path = (int**)malloc(sizeof(int*) * a->Nv);
	for (int i = 0; i < a->Nv; i++)
	{
		Distance[i] = (int*)malloc(sizeof(int) * a->Nv);
		Path[i]= (int*)malloc(sizeof(int) * a->Nv);
	}
	Floyd(a, Distance, Path);
	Read_Path(Path, 0, 9);





}
MyGraph CreateGraph(int VertexNum)//创建一个图并将邻接矩阵所有节点都初始化为0
{
	MyGraph a = (MyGraph)malloc(sizeof(struct GNode));
	a->G = (WeightType**)malloc(sizeof(WeightType*) * VertexNum);//G是一个指向指针的指针
	for (int i = 0; i < VertexNum; i++)
	{
		a->G[i] = (WeightType*)malloc(sizeof(WeightType) * VertexNum);//a->G[i]是一个指向int的指针
	}
	for (int i = 0; i < VertexNum; i++)
	{
		for (int j = 0; j < VertexNum; j++)
		{
			a->G[i][j] = INFINITY;
		}
	}
for (int j = 0; j < VertexNum; j++)
		{
			a->G[j][j] = 0;
		}
	a->Nv = VertexNum;
	a->Ne = 0;
	return a;
}
void InsertEdge(MyGraph Graph, Edge E)//创建无向图,所以G[V2][V1]也得改
{
	Graph->G[E->V1][E->V2] = E->weight;
	Graph->G[E->V2][E->V1] = E->weight;
}
MyGraph Build_Graph()
{
	int VertexNum;
	Edge E = (Edge)malloc(sizeof(struct ENode));
	printf("please Enter the number of the vertexs\n");
	scanf("%d", &VertexNum);
	MyGraph Graph = CreateGraph(VertexNum);
	printf("please Enter the number of the Edges\n");
	scanf("%d", &Graph->Ne);
	if (Graph->Ne)
	{
		for (int i = 0; i < Graph->Ne; i++)
		{
			scanf("%d %d %d", &E->V1, &E->V2, &E->weight);//无道路则为INFINITY
			InsertEdge(Graph, E);
		}
	}
	return Graph;

}
void Floyd(MyGraph Graph, int** Distance, int** Path)
{
	for (int i = 0; i < Graph->Nv; i++)
	{
		for (int j = 0; j < Graph->Nv; j++)
		{
			Distance[i][j] = Graph->G[i][j];
			Path[i][j] = -1;//-1代表i j之间无顶点
		}
	}
	for (int k = 0; k < Graph->Nv; k++)
	{
		for (int i = 0; i < Graph->Nv; i++)
		{
			for (int j = 0; j < Graph->Nv; j++)
			{
				if (Distance[i][j] > (Distance[i][k] + Distance[k][j]))
				{
					Distance[i][j] = Distance[i][k] + Distance[k][j];
					Path[i][j] = k;//i经过k到j
				}
			}
		}
	}

}
void Read_Path0(int** Path, int a, int b)//读取从a到b的路径
{

	if (Path[a][b] == -1)
		printf("%d\n", a);
	else
	{
		Read_Path0(Path, a, Path[a][b]);
		Read_Path0(Path, Path[a][b], b);
	}
}
void Read_Path(int** Path, int a, int b)
{
	Read_Path0(Path, a, b);
	printf("%d\n", b);
}

我认为妙的地方:要求Vi->Vj的最短路径,先求min(Vi->下标小于等于k->Vj)再min(Vi->下标小于等于k+1->Vj)......而且如果V(k+1)加进去了,那么min(Vi->下标小于等于k+1->Vj)=min(Vi->下标小于等于k+1)+min(下标小于等于k+1->Vj)=D^k[Vi][k+1]+D^k[K+1][Vj](数学归纳法,假设第K+1步可以得到Vi->下标小于等于k->Vj的矩阵D^k

还有Path我自己想的是Path[i][j]保存的是前一个点,然而是继善保存的是之间的点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值