算法导论第二十五章-所有结点对的最短路径问题-Cpp代码实现

这一章就实现了一个Floyd算法。

其中路径的表示没有采用书上的前驱表示,而是用每一对结点中开始结点的后继来表示。

floyd_warshall.h

#pragma once

/*************************************************
Author:董小歪
Date:2016-06-24
Description:算法导论第二十五章-所有结点对的最短路径问题-Cpp代码实现
**************************************************/

#ifndef FLOYD_WARSHALL_H
#define FLOYD_WARSHALL_H

#include <iostream>
#include <vector>

using namespace std;

class Floyd_Warshall
{
public:
	Floyd_Warshall(const vector<vector<int>> &_W);	//构造函数
	vector<vector<int>> floyd_warshall();			//Floyd算法
	void show_path();								//显示计算结果
	void show_vec(const vector<vector<int>> &vec);

private:
	vector<vector<int>> W;							//输入邻接矩阵
	vector<vector<int>> path;						//计算路径
	vector<vector<int>> D;							//计算距离
};

#endif // !FLOYD_WARSHALL_H


floyd_warshall.cpp

#include "floyd-warshall.h"

Floyd_Warshall::Floyd_Warshall(const vector<vector<int>> &_W) :W(_W)
{
	int n = W.size();
	path = vector<vector<int>>(n, vector<int>(n, -1));
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			if (W[i][j] < INT_MAX)
				path[i][j] = j;		//初始化路径。这里没有按书上的方法,存的是每一个点的后继而不是前驱。
}

vector<vector<int>> Floyd_Warshall::floyd_warshall()
{
	int n = W.size();
	D = W;
	for (int k = 0; k < n; ++k)
	{
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				if (D[i][j] > D[i][k] + D[k][j])
				{
					D[i][j] = D[i][k] + D[k][j];	//发现了更短的距离,取代前者
					path[i][j] = path[i][k];		//更新路径
				}
			}
		}
	}
	return D;
}

void Floyd_Warshall::show_path()
{
	int n = W.size();
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			printf("结点%d到结点%d的最短路径是为%d,\t", i, j, D[i][j]);
			int k = path[i][j];
			if (k == -1)
				printf("路径不存在\n");
			else
			{
				printf("(%d", i);
				while (k != j)
				{
					printf("->%d", k);
					k = path[k][j];
				}
				printf("->%d)\n", j);
			}
		}
	}
}

void Floyd_Warshall::show_vec(const vector<vector<int>> &vec)
{
	for (int i = 0; i < vec.size(); ++i)
	{
		for (int j = 0; j < vec[i].size(); ++j)
		{
			if (vec[i][j] < INT_MAX / 2)
				cout << vec[i][j] << "\t";
			else
				cout << "∞" << "\t";
		}
		cout << endl;
	}
}


测试代码:
main_entrance.cpp

#include "floyd-warshall.h"

int main()
{
	
	vector<vector<int>> W(5, vector<int>(5, INT_MAX / 2));
	W[0][1] = 3;	W[0][2] = 8;	W[0][4] = -4;
	W[1][3] = 1;	W[1][4] = 7;
	W[2][1] = 4;
	W[3][0] = 2;	W[3][2] = -5;
	W[4][3] = 6;
	for (int i = 0; i < W.size(); ++i)	W[i][i] = 0;
	Floyd_Warshall fw(W);
	cout << "初始化的邻接矩阵为:" << endl;
	fw.show_vec(W);
	cout << endl << "Floyd计算后的邻接矩阵为:" << endl;
	fw.show_vec(fw.floyd_warshall());
	cout << "每两个结点之间的路径:" << endl;
	fw.show_path();
	system("pause");
}

测试结果:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值