局部替换算法最小生成树

算法描述:

  从T=NULL开始

  for (图中的每条边e)

          if(加入e不构成环,则T=T+e)

          else e'是环上权重最大的边,T=T+e-e‘

算法实现

  可以看出上述的算法的关键之处就在于判断图中是否存在环以及找到环中最大的边。

判断是否有环:

   用dfs深度优先搜索,如果搜索过程中发现一个点u的邻接点v是灰色的,则说明这条边(u,v)是后向边。

找到环中最大边:

  从u开始寻找他的前驱点π[u],直到前驱点为v时停止,这过程中的所有点就是环中的所有的点。然后再求出最大的边就好了。

 

int linkedDgraph1::DFSCircle(int *res)
{
	int maxWeight = -1;
       time = 0;//计时器
	   for (int i = 0; i < 10000; i++)
	   {
		   color[i] = WHITE;
		   dTime[i] = 0;
		   fTime[i] = 0;
		   precursor[i] = 0;
		   low[i] = 0;
	   }
	for (int i = 0; i < verticeNumber; i++)
	{
		int u = point[i];
		if (color[u] == WHITE)
		{
			bool exist = false;
			int uu = 0;
			int vv = 0;
			DFSCircleVisit(u,exist,uu,vv);
			if (exist)//存在环
			{
				maxWeight = getWeight(vv,uu);
				int point1 = precursor[uu];//暂时保存前驱点
				while (point1 != vv)//当前驱点不等于起始点时
				{
					int temp = getWeight(point1, uu);//获取权值并进行比较
					if (maxWeight < temp)
					{
						maxWeight = temp;
						res[0] = uu;
						res[1] = point1;
					}
					uu = point1;
					point1 = precursor[point1];
				}
				int temp = getWeight(point1, uu);
				if (maxWeight < temp)
				{
					maxWeight = temp;
					res[0] = uu;
					res[1] = point1;
				}
				break;
			}
		}

	}
	return maxWeight;
}

void linkedDgraph1::DFSCircleVisit(int u,bool &exist,int &uu,int &vv)
{
	time += 1;
	dTime[u]  = time;
	color[u] = GRAY;
	graphNode *p = Adj[u].first();
	while (p != NULL)
	{
		int v = p->element;
		if(precursor[u]!=v)
		{ 
			if (color[v] == WHITE)//如果点是白色的
			{
				precursor[v] = u;
				DFSCircleVisit(v,exist,uu,vv);
				
				//cout << u << "-->" << v << endl;
			}
			if (color[v] == GRAY)//如果点是灰色的,说明有后向边即构成环
			{
				exist = true;
				uu = u;
				vv = v;
			}
			
		}
		p = p->next;
	}
	color[u] = BLACK;
	time += 1;
	fTime[u]  = time;
}

最后的生成树的代码:

void linkedDgraph1::Lsmst(linkedDgraph1 &G1)
{
	for (int i = 0; i < verticeNumber; i++)
	{
		int u = point[i];
		graphNode *p = Adj[u].first();
		while(p!=NULL)
		{
			int v = p->element;
			int temp = getWeight(u, v);
			G1.insertEdge(u, v, temp);
			G1.insertEdge(v, u, temp);
			int *a = new int[2];//保存结果
			 temp = G1.DFSCircle(a);
			if (temp != -1)//如果加入有环
			{
				G1.eraseEdge(a[0],a[1]);
				G1.eraseEdge(a[1], a[0]);
			}
			p = p->next;
		}
	}
}

 

你可能感兴趣的:(c++语言,算法实现)