您的位置:首页 > 编程语言 > C语言/C++

所有顶点间最短路径FloydWarshall算法实现文件C++

2011-09-17 12:23 806 查看
一个稍微特殊点的地方就是 min() 函数,考虑到要面对 Infinity 的情况,作乐多种检查来应对.

不仅可以计算出每对顶点间得最短路径,还支持打印路径.看书学,自己又一顿琢磨.懵的也好,会的也好,是睾出来了.下次再遇到这个问题,最起码的,知道有一种方法可以解决,哪怕不能立刻写出来.好像,也很难做到写过一次就记得住,对我来说.

//	graphRepresentAsAdjacentMatrix.cpp -- implement file.
//	2011-09-16-18.07 -- 2011-09-16-19.42 by Golden_Shadow.
//	2011-09-17-09.39 -- 2011-09-17-12.00 by Golden_Shadow.
#include "stdafx.h"
#include "graphRepresentAsAdjacentMatrix.h"

//	private methods of class Graph:
//	---------------------
int Graph ::m_min (int a, int partAOfB, int partBOfB)
{
	if (Infinity == (partAOfB & partBOfB))
	{
		//	Both partAOfB and partBOfB are Infinity.
		//	Return a, even through a is Infinity.
		return a ;
	}
	else if (Infinity == a)
	{
		//	Only a is Infinity
		if (partAOfB != Infinity && partBOfB != Infinity)
		{
			//	Neither partAOfB nor partBOfB is Infinity.
			return partAOfB + partBOfB ;
		}
		else
		{
			//	Either both partAOfB and partBOfB are Infinity or one of them is Infinity.
			return Infinity ;
		}
	}
	else
	{
		return a < partAOfB + partBOfB ? a : partAOfB + partBOfB ;
	}
}
//	---------------------

//	public methods of class Graph:
//	---------------------
//	Assume m_rows > 0
Graph ::Graph (unsigned int rows): m_rows(rows), m_currentRows(0)
{
	m_matrix = new int*[m_rows] ;
	for (int i = 0; i < m_rows; ++i)
	{
		m_matrix[i] = new int[m_rows] ;
	}
	m_distance = new int*[m_rows] ;
	for (int i = 0; i < m_rows; ++i)
	{
		m_distance[i] = new int[m_rows] ;
	}
	for (int i = 0; i != m_rows; ++i)
	{
		for (int j = 0; j != m_rows; ++j)
		{
			m_matrix[i][j] = Infinity ;
		}
	}
	m_parent = new int*[m_rows] ;
	for (int i = 0; i < m_rows; ++i)
	{
		m_parent[i] = new int[m_rows] ;
	}
	for (int i = 0; i != m_rows; ++i)
	{
		for (int j = 0; j != m_rows; ++j)
		{
			m_parent[i][j] = Nil ;
		}
	}
}
//	---------------------

//	---------------------
bool Graph ::importARowOfGraph (const std ::vector<int> & indexOfCurrentVertexAdjoinTo, const std ::vector<int> & weightOfCurrentVertexAdjoinTo)
{
	if (m_currentRows >= m_rows)
		return false ;
	if (indexOfCurrentVertexAdjoinTo.size() != weightOfCurrentVertexAdjoinTo.size())
		return false ;
	std ::vector<int> ::const_iterator indexIter = indexOfCurrentVertexAdjoinTo.begin() ;
	std ::vector<int> ::const_iterator weightIter = weightOfCurrentVertexAdjoinTo.begin() ;
	while (indexIter != indexOfCurrentVertexAdjoinTo.end())
	{
		m_matrix[m_currentRows][*indexIter] = *weightIter ;
		++indexIter ;
		++weightIter ;
	}
	m_matrix[m_currentRows][m_currentRows] = 0 ;
	++m_currentRows ;

	return true ;
}
//	---------------------

//	---------------------
void Graph ::floydWarshall (void)
{
	if (m_currentRows != m_rows)
		return ;
	//	Initialize m_distance as m_matrix.
	for (int i = 0; i < m_rows; ++i)
	{
		for (int j = 0; j < m_rows; ++j)
		{
			m_distance[i][j] = m_matrix[i][j] ;
		}
	}
	//	Initialize m_parent as m_matrix.
	for (int i = 0; i < m_rows; ++i)
	{
		for (int j = 0; j < m_rows; ++j)
		{
			if (i != j && m_matrix[i][j] != Infinity)
			{
				m_parent[i][j] = i ;
			}
		}
	}
	for (int k = 0; k != m_rows; ++k)
	{
		for (int i = 0; i != m_rows; ++i)
		{
			for (int j = 0; j != m_rows; ++j)
			{
				Weight temp = m_distance[i][j] ;
				m_distance[i][j] = m_min(m_distance[i][j], m_distance[i][k], m_distance[k][j]) ;
				if (m_distance[i][j] < temp)
				{
					m_parent[i][j] = m_parent[k][j] ;
				}
			}
		}
	}
}
//	---------------------

//	---------------------
//	Assume both startVertex and endVertex are in the range [0, |V|).
 void Graph ::printPathBetweenTwoVertexes (int startVertex, int endVertex)
{
	if (startVertex != endVertex)
	{
		printPathBetweenTwoVertexes(startVertex, m_parent[startVertex][endVertex]) ;
		std ::cout << "-> V[" << endVertex << "]" ;
	}
	else
		std ::cout << "V[" << startVertex << "]" ;
 }
//	---------------------

//	---------------------
Graph ::~Graph (void)
{
	for (int i = 0; i < m_rows; ++i)
	{
		delete []m_matrix[i] ;
	}
	delete []m_matrix ;
	for (int i = 0; i < m_rows; ++i)
	{
		delete []m_distance[i] ;
	}
	delete []m_distance ;
	for (int i = 0; i < m_rows; ++i)
	{
		delete []m_parent[i] ;
	}
	delete []m_parent ;
}
//	---------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: