封装好的Folyd建图,C++源码

Floyd建图是图论中运用最广的算法,也是图论的经典范例。网上此种代码为数不少,但是都比较零散且缺乏封装性,对于新接触的人来说学习起来耗时耗力。由于前段时间开始搞数模,所以我自己将这些代码进行封装整理,便于大家运用学习,绝对原创。

CFloyd_MakeMap.h文件:

/*Floyd算法建立最短路径*/

#ifndef CFloyd_MakeMap_h_
#define CFloyd_MakeMap_h_

#pragma warning(disable : 4786)			//屏蔽标准库的编译错误
#include "map"
#include "vector"
#define Maxm 1001


struct Point{
	Point(){};
	Point(int x,int y)
	{
		source=x;
		target=y;
	};
	int source;				//原城市
	int target;				//目标城市
	friend bool operator < (const struct Point &ls, const struct Point &rs);
};

inline bool operator < (const struct Point &ls, const struct Point &rs)
{return (ls.source < rs.source || (ls.source == rs.source && ls.target < rs.target));}

typedef std::map<Point,std::vector<int> >::iterator Iter_Map;
typedef std::vector<int>::iterator Iter_Vector;

class CFloyd_MakeMap
{
public:
	CFloyd_MakeMap();
	~CFloyd_MakeMap();
	void Initial();
	void Floyd_in(char *filename,int size);		//读入题目所给数据
	void Floyd_Trans_out(char*filename);		//将加权图保存到文件
	void Floyd_out(char *filename);			//将最短路径图保存到文件
	void MakeMap();					//建立最短路径图
	void MakePoint(int a,int b);			//建立最短节点图
	void Point_out(char*filename);			//将最短节点图保存到文件

	std::map<Point,std::vector<int> > m_point;	//保存最优节点						
	int (*m_Dist)[Maxm];				//保存最短距离(从下标1,1开始)	
	int m_Vertex;					//个数
	
private:
	void Root(int p,int q);				//递归改变输出次数k(如果有的话)
	int (*m_Path)[Maxm];				//保存递归时需要的节点
	int	*m_Line;
	int p,q,k,m;
}; 


#endif

CFloyd_MakeMap.cpp文件:

#include "CFloyd_MakeMap.h"
#include "fstream"
#include "iostream"

using namespace std;

CFloyd_MakeMap::CFloyd_MakeMap()
{
	Initial();
}
CFloyd_MakeMap::~CFloyd_MakeMap()
{
	delete []m_Dist;
	delete []m_Path;
	delete []m_Line;
}

void CFloyd_MakeMap::Initial()
{
	m_Path=new int[Maxm][Maxm];
	m_Dist=new int[Maxm][Maxm];
	m_Line=new int[Maxm];
	memset(m_Path,0,sizeof(m_Path));
	memset(m_Dist,0,sizeof(m_Dist));
	memset(m_Line,0,sizeof(m_Line));
	m_Vertex=0;
	p=0;q=0;k=0;m=0;
}

void CFloyd_MakeMap::Floyd_in(char*filename,int size)
{
	m_Vertex=size;
	ifstream fin(filename);
	if(!fin)
	{
		cerr<<"Don't find file for read in!"<<endl;
		exit(1);
	}
	for(p=1;p<=m_Vertex;p++)
	{
		for(q=1;q<=m_Vertex;q++)
			fin >> m_Dist[p][q];
	}
	fin.close();
}

void CFloyd_MakeMap::MakeMap()
{
	for(k=1;k<=m_Vertex;k++)						//k为插入的节点
	{
		for(p=1;p<=m_Vertex;p++)
			if (m_Dist[p][k]>0)
				for(q=1;q<=m_Vertex;q++)
					if (m_Dist[k][q]>0)
					{
						if (((m_Dist[p][q]>m_Dist[p][k]+m_Dist[k][q])||(m_Dist[p][q]==0))&&(p!=q))
						{
							m_Dist[p][q]=m_Dist[p][k]+m_Dist[k][q];
							m_Path[p][q]=k;		//保存插入的节点
						}
					}
	}
}

void CFloyd_MakeMap::Floyd_Trans_out(char* filename)
{
	ofstream fout_trans(filename);
	if(!fout_trans)
	{
		cerr<<"Can't set the file!"<<endl;
		exit(1);
	}
	for(p=1;p<=m_Vertex;p++)
	{
		for(q=1;q<=m_Vertex;q++)
		{
			fout_trans<<m_Dist[q][p]<<"	";
		}
		fout_trans<<endl;
	}
	fout_trans.close();
}

void CFloyd_MakeMap::Floyd_out(char *filename)
{
	ofstream fout_result(filename);
	if(!fout_result)
	{
		cerr<<"Can't set the file!"<<endl;
		exit(1);
	}
	for(p=1;p<=m_Vertex;p++)
	{
		for(q=1;q<=m_Vertex;q++)
		{
			fout_result<<m_Dist[p][q]<<"	";
		}
		fout_result<<endl;
	}
	fout_result.close();
}

void CFloyd_MakeMap::Root(int p,int q)					//递归改变输出次数k(如果有的话)
{
	if (m_Path[p][q]>0)
	{
		Root(p,m_Path[p][q]);
		Root(m_Path[p][q],q);
	}
	else
	{
		this->m_Line[k]=q;
		k++;
	}
}

void CFloyd_MakeMap::MakePoint(int a,int b)
{
    m_point.clear();
	for(p=a;p<=b;p++)
	{
		for(q=a;q<=b;q++)
		{
			if(p==q)continue;
			Point temp_position;
			temp_position.source=p;
			temp_position.target=q;

			vector<int> temp_point;
			temp_point.push_back(p);
			
			k=2;
			Root(p,q);
			for(m=2;m<=k-1;m++)
				temp_point.push_back(m_Line[m]);
			m_point.insert(make_pair(temp_position,temp_point));
		}
	}
}

void CFloyd_MakeMap::Point_out(char* filename)
{
	ofstream fout_point(filename);
	if(!fout_point)
	{
		cerr<<"Can't set file to save!"<<endl;
		exit(1);
	}
	Iter_Map iter;
	Iter_Vector iter_temp;
	for(iter=m_point.begin();iter!=m_point.end();++iter)
	{
		fout_point<<iter->first.source<<"->"<<iter->first.target<<" 路程为:"
			<<m_Dist[iter->first.source][iter->first.target]<<endl;
		for(iter_temp=iter->second.begin();iter_temp<iter->second.end();++iter_temp)
			fout_point<<*iter_temp<<" ";
		fout_point<<endl<<endl;
	}
	fout_point.close();
}

main.cpp测试文件:

//
//  main.cpp
//  CFloyd_MakeMap
//
//  Created by yaoshun on 13-6-10.
//  Copyright (c) 2013年 yaoshun. All rights reserved.
//

#include <iostream>
#include "time.h"

#include "CFloyd_MakeMap.h"

using namespace std;

int main(int argc, const char * argv[])
{
    //计时
	clock_t timeBegin, timeEnd;
    timeBegin = clock();

    
    CFloyd_MakeMap Floyd_map;
    Floyd_map.Floyd_in("data1.txt", 919);
    
    //将邻接矩阵翻转输出
    Floyd_map.Floyd_Trans_out("Floyd_Trans.xls");
    //建立Floyd图
    Floyd_map.MakeMap();
    //建立详细Floyd路径信息
    Floyd_map.MakePoint(1,34);
    
    //将结果保存输出
    Floyd_map.Floyd_out("Floyd_Result.xls");
    Floyd_map.Point_out("Floyd_path.out");
        
    timeEnd = clock();
	cout<<"花费的总时间为:"<<(double)(timeEnd-timeBegin)/ CLOCKS_PER_SEC<<"秒"<<endl;
    system("pause");
    return 0;
}

欢迎大家交流讨论改错。

点赞