寻找有向无环图中的强连通分支C++

本文介绍了一种改进的图论算法,包括图结构转换、DFS遍历和强连通分量查找。通过实例演示了如何使用DFS和图的邻接矩阵表示,实现图的转换和识别强连通分量,同时讨论了算法的优化和实现细节。

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

   话说,半年前接触过这个东西.昨天又接触,发现书上给的方法很好.去一趟DFS,回来按照去的完成时间,即从后往前再次对转置了的原图进行DFS.就是这样.

  话说啊,来到了网吧,没带身份证,在二楼跟一群男童在一间屋子...传完了出去准备晚饭,貌似今天心情突然好起来了.

  同样只是函数定义而已,没有经过任何算法的优化,完全就是按照主要的思想来进行的.最近算法东西前进得不多,在看<<via>>,加油咯.贴吧.

//	2011-08-21-21.15 -- 2011-08-21-23.33 by Golden_Shadow.
//	2011-08-22-16.26 -- 2011-08-22-17.01 by Golden_Shadow.

//	Set all vertexes V[startIndex] adjoines to has same index value in pArray.
//	They are in the same strongly connected component.
//	------------------------------------------------------------------------------------
void graphRepresentAsAdjacentMatrix ::m_dFS (const unsigned int startIndex, int * const pArray, const int index)
{
	m_STL_Vector_color[startIndex] = Color_Gray ;

	for (int i = 0; i < m_row; ++i)
	{
		if (m_matrix[startIndex][i] && Color_White == m_STL_Vector_color[i])
		{
			m_STL_Vector_color[i] = Color_Gray ;
			m_dFS(i, pArray, index) ;
		}
	}
	*(pArray + startIndex) = index ;
}

//	------------------------------------------------------------------------------------
bool graphRepresentAsAdjacentMatrix ::transfer (void)
{
	if (m_currentRow < m_row)
	{
		std ::cerr << "Fault, there is(are) " << m_row - m_currentRow << " edge(s) has(have) not been imported." << std ::endl ;
		return false ;
	}
	int * * assistantMatrix = new int *[m_row] ;
	if (NULL == assistantMatrix)
	{
		std ::cerr << "Out of space." << std ::endl ;
		return false ;
	}
	//	Create a assistant matrix to help transfer matrix.
	for (int i = 0; i < m_row; ++i)
	{
		assistantMatrix[i] = new int[m_row] ;
		if (NULL == assistantMatrix[i])
		{
			for (int j = i - 1; j >= 0; --j)
			{
				delete []assistantMatrix[j] ;
			}
			delete []assistantMatrix ;
		}
	}
	for (int i = 0; i < m_row; ++i)
	{
		for (int j = 0; j < m_row; ++j)
		{
			assistantMatrix[i][j] = false ;
		}
	}
	//	Record the transfered graph.
	//	Set m_matrix[i][j] = false, assistantMatrix[j][i] = true when m_matrix[i][j] = true.
	for (int i = 0; i < m_row; ++i)
	{
		for (int j = 0; j < m_row; ++j)
		{
			if (m_matrix[i][j])
			{
				m_matrix[i][j] = false ;
				assistantMatrix[j][i] = true ;
			}
		}
	}
	//	Then, copy assistantMatrix to m_matrix.
	for (int i = 0; i < m_row; ++i)
	{
		for (int j = 0; j < m_row; ++j)
		{
			if (assistantMatrix[i][j])
			{
				m_matrix[i][j] = true ;
			}
		}
	}
	//	Ok, free assistantMatrix.
	for (int i = 0; i < m_row; ++i)
	{
		delete []assistantMatrix[i] ;
	}
	delete []assistantMatrix ;

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

//	------------------------------------------------------------------------------------
//	This routine receive an array and a pointer points to an int.
//	It will find out all strongly connected components in the graph.
//	All vertexes in the same strongly connected component has same index in pArray.
//	If success, return true, return result by parameter pArray and pNumOfStronglyConnectedComponent.
//	Else, return false.
bool graphRepresentAsAdjacentMatrix ::findStronglyConnectedComponent (int * const pArray, int * const pNumOfStronglyConnectedComponent)
{
	if (m_currentRow < m_row)
	{
		std ::cerr << "Fault, there is(are) " << m_row - m_currentRow << " edge(s) has(have) not been imported." << std ::endl ;
		return false ;
	}
	if (NULL == pArray || NULL == pNumOfStronglyConnectedComponent)
	{
		return false ;
	}
	//	Run a depth first search to calculate finishing time of each vertex.
	for (int i = 0; i < m_row; ++i)
	{
		if (Color_White == m_STL_Vector_color[i])
		{
			m_dFS(i) ;
		}
	}
	//	Resetting m_STL_Vector_color and m_STL_Vector_indexOfParent for flowing m_dFS() called.
	m_resettingVectorColor() ;
	m_resettingVectorParent() ;
	//	Transfer the graph.
	if (!transfer())
	{
		//	transfer() return false,
		m_resettingAllVector() ;
		return false ;
	}
	//	Run a depth first search on the transfered graph in order of decreasing F[vertex].
	*pNumOfStronglyConnectedComponent = 0 ;
	while (1)
	{
		int maxFinishingTime = 0 ;
		int indexOfMaxFinishingTimeVertex = 0 ;
		//	Look up the vertex with max finishing time and its color is white.
		for (int i = 0; i < m_row; ++i)
		{
			if (Color_White == m_STL_Vector_color[i] && m_STL_Vector_indexOfTimeF[i] > maxFinishingTime)
			{
				maxFinishingTime = m_STL_Vector_indexOfTimeF[i] ;
				indexOfMaxFinishingTimeVertex = i ;
			}
		}
		if (maxFinishingTime != 0)
		{
			m_dFS(indexOfMaxFinishingTimeVertex, pArray, *pNumOfStronglyConnectedComponent) ;
			++(*pNumOfStronglyConnectedComponent) ;
		}
		else
		{
			//	All vertexes has been traveled.
			break ;
		}
	}
	m_resettingAllVector() ;
	m_time = 0 ;

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


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值