(番外)使用DFS和BFS实现拓扑排序
1.BFS实现
public class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
int[] incLinkCounts = new int[numCourses];
List<List<Integer>> adjs = new ArrayList<>(numCourses);
initialiseGraph(incLinkCounts, adjs, prerequisites);
//return solveByBFS(incLinkCounts, adjs);
return solveByBFS(incLinkCounts,adjs);
} private void initialiseGraph(int[] incLinkCounts, List<List<Integer>> adjs, int[][] prerequisites){
int n = incLinkCounts.length;
while (n-- > 0) adjs.add(new ArrayList<>());
for (int[] edge : prerequisites) {
incLinkCounts[edge[0]]++;
adjs.get(edge[1]).add(edge[0]);
}
} private int[] solveByBFS(int[] incLinkCounts, List<List<Integer>> adjs){
int[] order = new int[incLinkCounts.length];
Queue<Integer> toVisit = new ArrayDeque<>();
for (int i = 0; i < incLinkCounts.length; i++) {
if (incLinkCounts[i] == 0) toVisit.offer(i);
}
int visited = 0;
while (!toVisit.isEmpty()) {
int from = toVisit.poll();
order[visited++] = from;
for (int to : adjs.get(from)) {
incLinkCounts[to]--;
if (incLinkCounts[to] == 0) toVisit.offer(to);
}
}
return visited == incLinkCounts.length ? order : new int[0];
}
}
2.DFS实现
public class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
int[] incLinkCounts = new int[numCourses];
List<List<Integer>> adjs = new ArrayList<>(numCourses);
initialiseGraph(incLinkCounts, adjs, prerequisites);
//return solveByBFS(incLinkCounts, adjs);
return solveByDFS(adjs);
} private void initialiseGraph(int[] incLinkCounts, List<List<Integer>> adjs, int[][] prerequisites){
int n = incLinkCounts.length;
while (n-- > 0) adjs.add(new ArrayList<>());
for (int[] edge : prerequisites) {
incLinkCounts[edge[0]]++;
adjs.get(edge[1]).add(edge[0]);
}
} private int[] solveByBFS(int[] incLinkCounts, List<List<Integer>> adjs){
int[] order = new int[incLinkCounts.length];
Queue<Integer> toVisit = new ArrayDeque<>();
for (int i = 0; i < incLinkCounts.length; i++) {
if (incLinkCounts[i] == 0) toVisit.offer(i);
}
int visited = 0;
while (!toVisit.isEmpty()) {
int from = toVisit.poll();
order[visited++] = from;
for (int to : adjs.get(from)) {
incLinkCounts[to]--;
if (incLinkCounts[to] == 0) toVisit.offer(to);
}
}
return visited == incLinkCounts.length ? order : new int[0];
} private int[] solveByDFS(List<List<Integer>> adjs) {
BitSet hasCycle = new BitSet(1);
BitSet visited = new BitSet(adjs.size());
BitSet onStack = new BitSet(adjs.size());
Deque<Integer> order = new ArrayDeque<>();
for (int i = adjs.size() - 1; i >= 0; i--) {
if (visited.get(i) == false && hasOrder(i, adjs, visited, onStack, order) == false) return new int[0];
}
int[] orderArray = new int[adjs.size()];
for (int i = 0; !order.isEmpty(); i++) orderArray[i] = order.pop();
return orderArray;
} private boolean hasOrder(int from, List<List<Integer>> adjs, BitSet visited, BitSet onStack, Deque<Integer> order) {
visited.set(from);
onStack.set(from);
for (int to : adjs.get(from)) {
if (visited.get(to) == false) {
if (hasOrder(to, adjs, visited, onStack, order) == false) return false;
} else if (onStack.get(to) == true) {
return false;
}
}
onStack.clear(from);
order.push(from);
return true;
}
}
(番外)使用DFS和BFS实现拓扑排序的更多相关文章
- 图论相关知识(DFS、BFS、拓扑排序、最小代价生成树、最短路径)
图的存储 假设是n点m边的图: 邻接矩阵:很简单,但是遍历图的时间复杂度和空间复杂度都为n^2,不适合数据量大的情况 邻接表:略微复杂一丢丢,空间复杂度n+m,遍历图的时间复杂度为m,适用情况更广 前 ...
- hdu1532 用BFS求拓扑排序
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 题目给出一些点对之间的先后顺序,要求给出一个字典序最小的拓扑排列.对于拓扑排序的问题,我们有DF ...
- bfs+dfs乱搞+类似拓扑排序——cf1182D
代码不知道上了多少补丁..终于过了 用类似拓扑排序的办法收缩整棵树得到x,然后找到x直连的最远的和最近的点 只有这三个点可能是根,依次判一下即可 另外题解的第一种方法时找直径,然后判两端点+重心+所有 ...
- 强大的dfs(用处1——拓扑排序【xdoj1025】,用处二——求强联通分量【ccf高速公路】)当然dfs用处多着咧
xdoj 1025 亮亮最近在玩一款叫做“梦想庄园”的经营游戏.在游戏中,你可以耕种,养羊甚至建造纺织厂. 如果你需要制造衣服,你首先得有布匹和毛线.布匹由棉花纺织而成:毛线由羊毛制成,而羊需要饲料才 ...
- Luogu2164 SHOI2007 交通网络 期望、BFS、拓扑排序
传送门 题目还算不难吧 首先我们枚举点$i$,将其他所有点到这个点的最短路求出来 然后我们在这一次建出的最短路$DAG$的反图上进行拓扑排序.假设我们算到了点$j$,点$j$的人流量为$t_j$,点$ ...
- leetcode_课程表(BFS、拓扑排序)
题目描述: 你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 .在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹 ...
- 3076: 神经网络(bfs和拓扑排序)
3076: 神经网络 时间限制: 1 Sec 内存限制: 125 MB提交: 7 解决: 5[提交][状态][讨论版][命题人:外部导入][Edit] [TestData] [同步数据] 题目描述 ...
- 拓扑排序详解(梅开二度之dfs版按字典序输出拓扑路径+dfs版输出全部拓扑路径
什么是拓扑排序? 先穿袜子再穿鞋,先当孙子再当爷.这就是拓扑排序! 拓扑排序说白了其实不太算是一种排序算法,但又像是一种排序(我是不是说了个废话qwq) 他其实是一个有向无环图(DAG, Direct ...
- Ordering Tasks(拓扑排序+dfs)
Ordering Tasks John has n tasks to do. Unfortunately, the tasks are not independent and the executio ...
随机推荐
- IntelliJ IDEA中配置reportNG
找了好多资料,各种设置都是eclipse上面的.后来发现原来就在Run->Edit Configurations->TestNG->Configuration->Listenn ...
- SwiftyJSON 中文介绍
SwiftyJSON makes it easy to deal with JSON data in Swift. Why is the typical JSON handling in Swift ...
- 解决:错误 14274: 无法添加、更新或删除 SQL 服务器上的作业的问题一例
今天在修改 SQL服务器上 以前的作业任务,打算把作业的执行时间修改成新的时间,结果修改好点确定, 结果出现了以下错误! --------------------------- Microsoft ...
- ES6 中的 Set、Map 和 WeakMap
Set 是 ES6 新增的有序列表集合,它不会包含重复项. Set 支持 add(item) 方法,用来向 Set 添加任意类型的元素,如果已经添加过则自动忽略: has(item) 方法用来检测 S ...
- python 字典访问的三种方法
定义字典 dic = {'a':"hello",'b':"how",'c':"you"} 方法一: for key in dic: prin ...
- Notepad++前端开发常用插件介绍 - BorisHuai前端修炼 - 博客频道 - CSDN
Notepad++前端开发常用插件介绍 - BorisHuai前端修炼 - 博客频道 - CSDN.NET http://blog.csdn.net/borishuai/article/details ...
- WCF学习心得----(五)生成客户端
WCF学习心得----(五)生成客户端 1. 通过Svcutil.exe工具直接生成客户端 1.1 将服务承载于IIS上 1.1.1 在IIS中新建网站,所示效果如下图: 1.1.2 ...
- 关于SqlServer的DBHelper类以及数据分页
前端: <My:AspNetPager class="arPage" PageSize="20" UrlPaging="true" r ...
- 读书笔记:Ross:概率模型导论:方差和协方差
例2.34 考虑N个人,一些人赞同某个提议,另一些人反对.假定Np个人赞同,N-Np人反对,p未知.现在想要通过随机选取n个人调查他们的态度,并由此来估计总体中赞同这个提议的人员比例p. 设Xi=1表 ...
- bzoj3136
Description 给定m个素数和Q个询问.每个询问有n个人,每次操作可以任意选择其中的一个素数p(素数可以重复使用),然后去掉剩余人数 mod p个人.对于每个询问,我们想知道,至少需要多少步操 ...