浅谈拓扑排序(DFS学习)

给定一张有向无环图

若一个由图中所有点构成的序列A满足:对于图中每条边(x,y),x在A中都出现在A之前,则称A是该有向无环图顶点的一个拓扑序。

求解序列A的过程就成为拓扑排序。

拓扑排序过程的思想非常简单,我们只需要不断选择图中入度为0的节点x,然后把x连向的点入度减1。

广搜过程实现(DFS):

1.建立空的拓扑序列A。

2.预处理出所有点的入度deg[i],起初把所有入度为0的点入队。

3.取出队头节点x,把x加入拓扑序列A的末尾。

4.对于从x出发的每条边(x,y),把deg[y]减1。若被减为0,则把y入队。

5.重复3~4步直到队列为空,此时A即为所求

PS:如序列A的长度小于图中节点数量,则说明某些节点未被遍历,即图中存在环。

具体(部分)代码实现:

void add(int x,int y)//在邻接表中添加一条有向边 
{
	ver[++tot]=y;
	next[tot]=head[x];
	head[x]=tot;
	deg[y]++;
	return; 
}
void topsort()//拓扑排序 
{
 	 queue<int> q;
 	 for(int i=1;i<=n;i++)
 	 {
 	 	if(deg[i]==0) q.push(i);
 	 }
 	 while(q.size())
 	 {
 	 	int x=q.front();
 	 	q.pop();
 	 	a[++cnt]=x;
 	 	for(int i=head[x];i;i=next[i])
 	 	{
 	 		int y=ver[i];
 	 		if(--deg[y]==0) q.push(y);
 	 	}
 	 }
 	 return;
}
int main()
{
 	cin>>n>>m;
 	for(int i=1;i<=n;i++)
 	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
    }
    topsort();
    for(int i=1;i<=n;i++)
    {
  		printf("%d",a[i]);
 	}
 	return 0;
}

Orz

posted @ 2019-07-30 19:58  Ankiia  阅读(245)  评论(0编辑  收藏  举报