Toposort(拓扑排序)——DFS递归回溯版
来源:互联网 发布:菠萝饭软件 编辑:程序博客网 时间:2024/05/17 00:50
拓扑排序简单来说就是把一个图的所有节点排序,使得每一条有向边(u,v)对应的u都排在v的前面。
拓扑排序最大的用途就是判断一个有向图是否有环,当然判断还有一种方法就是Floyd算法。
如果用邻接表的话拓扑排序的时间复杂度是O(N*E),邻接矩阵是O(N^2),N表示顶点数,E表示边数,Floyd时间复杂度是O(N^3)。
性质
1、 拓扑排序在有向无环图中才能排出有效的序列,否则能判断该有向图有环。
2、如果输入的有向图中的点,不存在入度为0的点,则该有向图存在回路
3、如果存在的入度为0的点大于一个,则该有向图肯定不存在一个可以确定的拓扑序列但并不妨碍拓扑排序
下面给出核心程序:
vector<int>g[N];//邻接表存储int vis[N],topo[N],cnt;bool dfs(int u){ vis[u] = -1;//-1用来表示顶点u正在访问 for(int i = 0 ; i < g[u].size() ; i ++) { if(vis[g[u][i]] == -1)//表示这个点进入了两次,肯定出现了环 return false; else if(vis[g[u][i]] == 0) { dfs(g[u][i]); } } vis[u] = 1; topo[cnt++] = u;//放到结果数组里,输出的时候记得倒序输出,(回溯的原因) return true;}bool toposort(int n){ memset(vis,0,sizeof(vis)); for(int i = 1 ; i <= n ; i ++) { if(!vis[i]) { if(!dfs(i)) return false;//huan } } return true;}
非递归代码,这段代码无法判断是否有环
for(i=1;i<=n;i++)//外层循环n次,in[]数组用来记录每个点的入度{j=1;while(in[j]!=0) j++;//从第一个节点开始找到一个节点入度为0的节点ans[i]=j;//存储答案in[j]=-1;//将该节点的入度更新为-1for( k=1;k<=n;k++)//将所有与节点j相连的节点的入度值全部减1if(vis[j][k]==1) in[k]--;}
拓扑排序还有一个重要的功能就是判断节点是一条链,还是在某个节点出现了分叉,这个很好理解,就用上面的非递归代码就可以判断,每次找入度为0的节点数目只能有1个,如果出现了两个则说明在该节点的父亲节点出现了分叉。
1 0
- Toposort(拓扑排序)——DFS递归回溯版
- Toposort(拓扑排序)——DFS递归回溯版
- Toposort(拓扑排序)——DFS递归回溯版
- 拓扑排序(Toposort)
- poj1270Following Orders(拓扑排序+dfs回溯)
- 拓扑排序 toposort
- Toposort(拓扑排序)
- 拓扑排序toposort 模板
- HDU 5638 Toposort(贪心+优先队列+拓扑排序)
- HDU 5638 Toposort 拓扑排序 优先队列
- 图的邻接表的遍历(DFS(递归,非递归),BFS,拓扑排序)
- 图论的各种姿势(中) Toposort拓扑排序 学习笔记 POJ2367 CODE[VS]2833
- 拓扑排序+DFS(POJ1270)
- 拓扑排序(BFS,DFS)
- uva10305(拓扑排序dfs)
- hdu5438(拓扑排序+dfs)
- DFS(深度搜索)——基于回溯法和递归
- [LeetCode]Permutations(回溯&&DFS&&递归!!!!)
- Java内存泄露的理解与解决
- iOS(iPhone,iPad))开发(Objective-C)开发库常用库索引
- Hog 和 CamShift 结合, 这个就是 非常的粗糙的 代码堆积
- Sql Server 主从数据库配置
- Android 传感器使用与开发-补充2(使用传感器的最佳实践)
- Toposort(拓扑排序)——DFS递归回溯版
- 多态小程序1
- CURL库在C++程序中的运用浅析
- iOS多线程的初步研究(一)
- python 读写 csv文件
- IIS重装后,重新注册.net framework 版本 -- aspnet_regiis.exe
- Android ProgressBar 样式实现原理
- 最短路算法 :Bellman-ford算法 & Dijkstra算法 & floyd算法 & SPFA算法 详解
- ole time(coledatetime) 转time_t(c time)