有向无环图单源点最短路径C++

本文介绍了一种应用于有向无环图(DAG)的单源点最短路径算法,该算法通过拓扑排序来高效地计算从源点到所有其他顶点的最短路径。文中详细解释了关键函数的实现,包括初始化源点、计算两点间距离、松弛操作及深度优先搜索等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   有向无环图上的单源点最短路径算法,用到了拓扑排序,很好的思想.

  给出了用到的函数,贴出来咯.

//	DAGShortestPathCalculate.cpp -- 2011-09-05-18.35
//	private methods declare.
void m_initializeSingleSource (int sourceVertex) ;
int m_distanceBetweenTwoVertexes (int startVertex, int endVertex) ;
void m_relax (int startVertex, int endVertex) ;
void m_deapthFirstSearch (vector<Vertex> ::size_type currentVertex,  deque<int> * pTopLogoicOrder) ;
//	public methods declare.
void topLogicalSort (deque<int> * pTopLogoicOrder) ;
void calculateShortestPath (int sourceVertex) ;

//	private methods implement.
//	---------------------
//	Assume the graph has been imported perfectly and
//	0 <= sourceVertex < m_size.
void graphRepresentAsAdjacentList ::m_initializeSingleSource (int sourceVertex)
{
	for (vector<int> ::iterator iter = m_distanceVector.begin(); iter != m_distanceVector.end(); ++iter)
	{
		*iter = Infinity ;
	}
	for (vector<size_t> ::iterator iter = m_parentVector.begin(); iter != m_parentVector.end(); ++iter)
	{
		*iter = Nil ;
	}
	m_distanceVector[sourceVertex] = 0 ;
}
//	---------------------

//	---------------------
int graphRepresentAsAdjacentList ::m_distanceBetweenTwoVertexes (int startVertex, int endVertex)
{
	Vertex * scan = m_adjacentListVector[startVertex].next ;

	while (scan != NULL)
	{
		if (endVertex == scan ->indexInAdjacentList)
			return scan ->weight ;
		scan = scan ->next ;
	}
	
	return Infinity ;
}
//	---------------------

//	---------------------
//	Assume both startVertex and endVertex are in the correct range.
void graphRepresentAsAdjacentList ::m_relax (int startVertex, int endVertex)
{
	if (m_distanceVector[endVertex] > m_distanceVector[startVertex] + m_distanceBetweenTwoVertexes(startVertex, endVertex))
	{
		m_distanceVector[endVertex] = m_distanceVector[startVertex] + m_distanceBetweenTwoVertexes(startVertex, endVertex) ;
		m_parentVector[endVertex] = startVertex ;
	}
}
//	---------------------

//	---------------------
void graphRepresentAsAdjacentList ::m_deapthFirstSearch (vector<Vertex> ::size_type currentVertex, deque<int> * pTopLogoicOrder)
{
	m_colorVector[currentVertex] = Color_Gray ;
	Vertex * scan = m_adjacentListVector[currentVertex].next ;
	while (scan != NULL)
	{
		if (Color_White == m_colorVector[scan ->indexInAdjacentList])
		{
			m_parentVector[scan ->indexInAdjacentList] = currentVertex ;
			m_deapthFirstSearch(scan ->indexInAdjacentList, pTopLogoicOrder) ;
		}
		scan = scan ->next ;
	}
	m_colorVector[currentVertex] = Color_Black ;
	pTopLogoicOrder ->push_front(static_cast<int> (currentVertex)) ;
}
//	---------------------

//	publicmethods implement.
//	---------------------
void graphRepresentAsAdjacentList ::topLogicalSort (deque<int> * pTopLogoicOrder)
{
	vector<Vertex> ::size_type currentVertex = 0 ;
	while (currentVertex != m_adjacentListVector.size())
	{
		if (Color_White == m_colorVector[currentVertex])
		{
			m_parentVector[currentVertex] = HasNotAParent ;
			m_deapthFirstSearch(currentVertex, pTopLogoicOrder) ;
		}
		++currentVertex ;
	}
	//	Reset m_colorVector.
	vector<Color> ::iterator iterC = m_colorVector.begin() ;
	while (iterC != m_colorVector.end())
	{
		*iterC = Color_White ;
		++iterC ;
	}
}
//	---------------------

//	---------------------
void graphRepresentAsAdjacentList ::calculateShortestPath (int sourceVertex)
{
	deque<int> topLogoicOrder ;
	topLogicalSort(&topLogoicOrder) ;
	m_initializeSingleSource(sourceVertex) ;
	//	For the first |V| - 1 vertexes, taken in toplogically sorted order.
	deque<int> ::size_type i = 0 ;
	while (i != topLogoicOrder.size() - 1)
	{
		Vertex * scan = m_adjacentListVector[i].next ;
		while (scan != NULL)
		{
			m_relax(m_adjacentListVector[i].indexInAdjacentList, scan ->indexInAdjacentList) ;
			scan = scan ->next ;
		}
		++i ;
	}
}
//	---------------------
//	---------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值