拓扑排序 toposort

拓扑排序详解
本文详细介绍了拓扑排序的概念及其在有向无环图(DAG)中的应用,包括两种实现方式:基于广度优先搜索(BFS)的方法和基于深度优先搜索(DFS)的方法,并附带环的检测逻辑。

大意:

        对于DAG(有向无环图),把图中所有结点排序,使得每一条有向边(u, v)对应的u都排在v的前面。直观地说,就是用一条线把有向图

中所有点连起来(当然是遵循有向边的)。

注:①有环图是不存在拓扑排序的。(因此可以用来判断图是否有环)。

      ②一个DAG可能有多个拓扑序列。

 

实现:

      主要有两种实现方法:

 

① bfs版:

(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边. 
(3)重复上述两步,直到剩余的网中不再存在没有前驱的顶点为止.

 

② dfs版:

详见代码。(by Rujia Liu)

带有环判断。

//从编号小的开始,【一直走,直到这条链走完,】 //再走另外的,于是不会破坏设定的二元关系 //================================================================ #include<stdio.h> #include<string.h> const int MAXN = 1000; int n, m, G[MAXN][MAXN]; int c[MAXN]; int topo[MAXN], t; bool dfs(int u){ c[u] = -1; for(int v = 0; v < n; v++) if(G[u][v]) { if(c[v]<0) return false; //正在访问,说明成环了 else if(!c[v]) dfs(v); //未访问 则访问它 } c[u] = 1; topo[--t]=u; //!!!加到当前拓扑序的首部 return true; } bool toposort(){ t = n; //t是n的temp memset(c, 0, sizeof(c)); //访问状态,初始为未访问过 0 -1 1 for(int u = 0; u < n; u++) if(!c[u]) if(!dfs(u)) return false; return true; } int main() { scanf("%d%d", &n, &m); //n个变量(默认0~n-1) m个二元组 memset(G, 0, sizeof(G)); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); G[u][v] = 1; //存在这个二元关系 u->v } if(toposort()) { for(int i = 0; i < n; i++) printf("%d/n", topo[i]); //正着输出的 } else //若存在有向环 printf("No/n"); }

转载于:https://www.cnblogs.com/tclh123/archive/2011/04/06/6171780.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值