拓扑排序能否成功,其实就是看有没有环

  • 有环:说明环内结点互为前置,永远也不可能完成
  • 无环:是线性的,可以完成

DFS方法

思路:

逆向思维,遍历到边界点(无邻接点相当于叶子),再不断回溯将结点加入到结果中,得到的是拓扑排序的逆序,进行反转即可得到拓扑序列。

遍历过程中判断是否有环。

注意:要使用vist[]标记三种状态。假如只标记两种状态,则下面这种情况会判定为false,但其实是true

代码

class Solution {
// 找到出度为0的点,
vector<int> res;
vector<int> g[2005];
int vist[2005]; // 1:正在遍历中 0:未遍历 2:已经完成了遍历
bool isLegal = true;
public:
void dfs(int x){
vist[x] = 1;
for(int i = 0;i < g[x].size();i++){
int nex = g[x][i];
if(vist[nex] == 0){
if(!isLegal) return ;
dfs(nex);
}else if(vist[nex] == 1){
isLegal = false;
return;
}
}
vist[x] = 2;
res.push_back(x);
} vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
int n = prerequisites.size();
for(int i = 0;i < n;i++){
int a = prerequisites[i][0], b = prerequisites[i][1];
g[b].push_back(a);
}
for(int i = 0;i < numCourses;i++){
if(!vist[i]) dfs(i);
} if(!isLegal) return {};
reverse(res.begin(),res.end());
return res;
}
};

BFS方法

思路

正向,从入度为0的点开始正向遍历,使用每将一个点加入结果(删去),该点的邻接点的入度-1。若邻接点的入度减为0,则可以加入队列。最后结果集的数量应当等于课程的数量。

代码

/*
拓扑排序(BFS)
*/
#include <bits/stdc++.h>
using namespace std; class Solution {
// 构建图,并初始化每个结点的入度
// 利用队列进行拓扑排序,不断的删除点,更新入度
vector<int> res;
int inDegree[2005];
vector<int> g[2005];
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
int n = prerequisites.size();
for(int i = 0;i < n;i++){
int a = prerequisites[i][0], b = prerequisites[i][1];
g[b].push_back(a);
inDegree[a]++;
}
queue<int> q;
// 寻找源点
for(int i = 0;i < numCourses;i++){
if(inDegree[i] == 0){
q.push(i);
}
}
while(!q.empty()){
int now = q.front();
q.pop();
res.push_back(now);
for(int i = 0;i < g[now].size();i++){
inDegree[g[now][i]]--;
if(inDegree[g[now][i]] == 0){
q.push(g[now][i]);
}
}
}
if(res.size() != numCourses) return {};
return res;
}
};

最新文章

  1. 从零开始编写自己的C#框架(25)——网站部署
  2. (十二)Maven生命周期和插件
  3. windows核心编程 - 线程基础
  4. Enterprise Architect 学习 之 活动图
  5. let it be
  6. Codeforces 720A. Closing ceremony
  7. 用thinkphp写的一个例子:抓取网站的内容并且保存到本地
  8. 禁止苹果浏览器Safari将数字识别成电话号码的方法
  9. SSH整合之spring整合struts2(续上)
  10. c# 多线程创建 ---简单
  11. 浅谈 Scala 中下划线的用途
  12. 配置Synergy(Server : XP, client: Win7)
  13. swt
  14. ORC 文件存储格式
  15. 针对Jigsaw勒索软件的解锁工具
  16. Can not find the tag library descriptor for &quot;/struts-tags&quot;`
  17. Django的视图系统
  18. ajax请求提交到controller后总是不成功
  19. 深入理解Spring的容器内事件发布监听机制
  20. 160427、CSS3实战笔记--多列布局

热门文章

  1. windows 使用自带的cmd终端进行文件MD5校验
  2. kube-scheduler源码分析(1)-初始化与启动分析
  3. FutureTask类的get方法如何实现线程同步等待
  4. Java不支持协程?那是你不知道Quasar!
  5. [镜像转换] ova文件转换成raw文件, 导入到openstack
  6. 强力推荐!五款能让你成为Excel“高手”的Excel插件
  7. 5、CPU 的线程与操作系统的线程有何关系?操作系统中的进程和线程是什么关系?
  8. mataplotlib篇(开篇)
  9. .Net Core中无处不在的Async/Await是如何提升性能的?
  10. Go基础知识梳理(四)