其他分享
首页 > 其他分享> > 拓扑排序

拓扑排序

作者:互联网

基于BFS的拓扑排序

先将所有入度为0的点放入队列中(顺序无关紧要),每次将队首弹出的点加入拓扑序列中,然后将该点所有的相邻点入度减1,将入度减为0的点入队。
当队列为空时,若所有点都以加入拓扑序列,则完成退出,反之该图不存在拓扑序列。
参考代码

void topo(){
    for(int i=1;i<=n;++i){
        if(ind[i]==0){q.push(i);
        ts[++tot]=i;}
    }
    int now,next;
    while(!q.empty()){
        now=q.front();
        q.pop();
        for(int i=0;i<node[now].size();++i){
            next=node[now][i];
            if(--ind[next]==0){
                q.push(next);
                ts[++tot]=next;
            }
        }
    }

基于DFS的拓扑排序

首先在一个图中使用dfs会产生一个深搜优先生成树。

黑色的边叫树边,这些边构成了深搜优先生成树。
红色的边叫返祖边,这些边指向祖先。
绿色的边叫前向边,这些边直线孙子,孙孙子。。。(注意不包括儿子)。
蓝色的边叫横插边,这些边上的两个节点没有子孙关系(相对于深搜优先生成树来讲)。
显然一个图中只有不产生返祖边才能有拓扑排序。

bool dfs(int s){
	vis[s]=-1;
	int next;
	for(int i=0;i<node[s].size();++i){
		next=node[s][i];
		if(vis[next]<0)return false;//发现返祖边,-1是为了区分子孙与祖先 
		if(vis[next]==0&&!dfs(next))return false; 
	}
	vis[s]=1;
	ts[tot--]=s;//加入拓扑排序
	return true; 
}
bool topo(){
	tot=n;
	bool f=1;
  for(int i=1;i<=n;++i){
  	if(ind[i]==0&&vis[i]==0){
  		f=dfs(i);
  		if(f==0)return false;
  	}
  }
}

标签:int,拓扑,dfs,返祖,序列,排序
来源: https://www.cnblogs.com/hetailang/p/16219830.html