1. 程式人生 > >最短路徑之弗洛伊德演算法(Floyd)

最短路徑之弗洛伊德演算法(Floyd)

http://blog.csdn.net/ganze_12345/article/details/12164389自己寫的對於這篇文章的改進。怎麼說呢,之前我還認為是因為題目的問題所以要用這種笨方法,可是現在覺得完全是因為自己思維太狹隘了和基本知識的掌握不牢所致,現在通過網上一片文章的啟示寫了如下程式碼。

#include <string>
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;
//問題描述
//
//高階題:地鐵換乘
//已知2條地鐵線路,其中A為環線,B為東西向線路,線路都是雙向的。經過的站點名分別如下,兩條線交叉的換乘點用T1、T2表示。編寫程式,任意輸入兩個站點名稱,輸出乘坐地鐵最少需要經過的車站數量(含輸入的起點和終點,換乘站點只計算一次)。
//地鐵線A(環線)經過車站:A1??A2??A3??A4??A5??A6??A7??A8??A9??T1??A10??A11??A12??A13??T2??A14??A15??A16??A17??A18
//地鐵線A(直線)經過車站:B1??B2??B3??B4??B5??T1??B6??B7??B8??B9??B10??T2??B11??B12??B13??B14??B15
//
//輸入:輸入兩個不同的站名
//輸出:輸出最少經過的站數,含輸入的起點和終點,換乘站點只計算一次

const static string RoutingName[] = {"A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",  
										"A11","A12","A13","A14","A15","A16","A17","A18",  
									 "B1","B2","B3","B4","B5","B6","B7","B8","B9","B10",  
									 "B11","B12","B13","B14","B15","T1","T2"};
const static unsigned int DotNumber = sizeof(RoutingName)/sizeof(string);
//路
class Rout
{
public:
	int power;//權值
	bool exitMilestone;//是否存在拐點
	int milestone;//拐點
	Rout():exitMilestone(false){};
};
//鄰接矩陣
class Matrix
{
private:
	string start;//起點
	string end;//終點
	enum
	{
		MAXSIZE=DotNumber//鄰接矩陣大小
	};
	void SearchMap(list<int>::iterator begin,list<int>::iterator end,list<int> &l)
	{//路徑搜尋
		Rout &r = (*Matrix::MatrixMap)[*begin][*end];
		if(r.exitMilestone)
		{
			list<int>::iterator temp = begin;
			l.insert(end,r.milestone);
			SearchMap(temp,++begin,l);
			SearchMap(begin,end,l);
		}
	}
public:
	Matrix(string start,string end):start(start),end(end){};
	static Rout (*MatrixMap)[Matrix::MAXSIZE][Matrix::MAXSIZE];//鄰接矩陣指標
	static void* InitMatrixMap()
	{//初始化鄰接矩陣
		Rout **p = new Rout*[Matrix::MAXSIZE];
		Rout *temp = new Rout[Matrix::MAXSIZE*Matrix::MAXSIZE];
		//構建連續空間
		for(unsigned int i = 0;i < Matrix::MAXSIZE;++i)
			p[i] = &temp[i*Matrix::MAXSIZE];
		//權值賦值
		for(unsigned int i = 0;i < Matrix::MAXSIZE;++i)
			for(unsigned int j = 0;j < Matrix::MAXSIZE;++j)
			{
				if(i == j)
					p[i][j].power = 0;
				else
					p[i][j].power = 65535;
			}
		const int AR[] = {1,2,3,4,5,6,7,8,9,34,10,11,12,13,35,14,15,16,17,18,1};//A路
		const int BR[] = {19,20,21,22,23,34,24,25,26,27,28,35,29,30,31,32,33};//B路
		for(unsigned int i = 0;i < sizeof(AR)/sizeof(int)-1;++i)
		{
			p[AR[i]-1][AR[i+1]-1].power = 1;
			p[AR[i+1]-1][AR[i]-1].power = 1;
		}
		for(unsigned int i = 0;i < sizeof(BR)/sizeof(int)-1;++i)
		{
			p[BR[i]-1][BR[i+1]-1].power = 1;
			p[BR[i+1]-1][BR[i]-1].power = 1;
		}
		delete[] p;
		return temp;
	}; 
	static void Floyd()
	{//FLOYD演算法
		for(int i = 0;i < DotNumber;++i)
			for(int j = 0;j < DotNumber;++j)
				for(int k = 0;k < DotNumber;++k)
				{
					if((*Matrix::MatrixMap)[j][k].power > ((*Matrix::MatrixMap)[j][i].power + (*Matrix::MatrixMap)[i][k].power))
					{
						(*Matrix::MatrixMap)[j][k].power = ((*Matrix::MatrixMap)[j][i].power + (*Matrix::MatrixMap)[i][k].power);
						(*Matrix::MatrixMap)[j][k].exitMilestone = true;
						(*Matrix::MatrixMap)[j][k].milestone = i;//記錄下拐點
					}
				}
	}
	static void DeleteMatrix()
	{//刪除初始陣列
		delete [] (Matrix::MatrixMap);
		Matrix::MatrixMap = NULL;
	}
	void GetBestRouting()
	{//得出最短路徑
		int i = find(RoutingName,RoutingName+DotNumber,start)-RoutingName,j = find(RoutingName,RoutingName+DotNumber,end)-RoutingName;
		if(i == DotNumber || j == DotNumber)
		{
			cout<<"輸入錯誤"<<endl;
			return ;
		}
		Rout* r = &(*Matrix::MatrixMap)[i][j];
		cout<<start<<"到"<<end<<"最短站點數為:"<<r->power+1<<endl;
		list<int> Station;
		Station.push_back(i);
		Station.push_back(j);
		this->SearchMap(Station.begin(),++Station.begin(),Station);
		cout<<"途中經過的站為:";
		for(list<int>::iterator begin = Station.begin();begin != Station.end();++begin)
		{
			cout<<RoutingName[*begin]<<"	";
		}
		cout<<endl;
	}
};
Rout(*Matrix::MatrixMap)[Matrix::MAXSIZE][Matrix::MAXSIZE] 
= (Rout (*)[Matrix::MAXSIZE][Matrix::MAXSIZE])Matrix::InitMatrixMap();//初始化

int main(int argc, char* argv[])
{
	Matrix::Floyd();
	string start,end;
	cout<<"輸入起點和終點"<<endl;
	cin>>start>>end;
	Matrix(start,end).GetBestRouting();
	system("pause");
	Matrix::DeleteMatrix();
	return 0;
}

唉,繼續學習,共同努力