算法练习(28):Course Schedule II

来源:互联网 发布:生态养殖 知乎 编辑:程序博客网 时间:2024/06/04 23:50

题意:给出有向图,找出它的拓扑排序

分析与思路:同样还是Course Schedule I(上一个博客)的思路,只不过在每次访问完一个结点的时候把它push起来,为什么呢?因为拓扑排序实际上就是结点按post值从小到大排序的结果,为什么呢?因此拓扑排序后一个结点的进行需要前一个结点的事情完成(遍历完),而post值代表完成的时间,所以,道理很简单(post是什么,还有基本深搜的思路参考上一个博客Course Schedule I的分析与思路,这里只讲额外的思路)

代码:

class Solution {public:vector<bool> isVisited;//可以用pre代替的vector<int> pre;vector<int> post;vector<int> result;int clock;bool dfs(int nowNode, vector<pair<int, int>>& prerequisites) {isVisited[nowNode] = true;pre[nowNode] = clock++;for (int i = 0; i < prerequisites.size(); i++) {if (prerequisites[i].first == nowNode) {if (isVisited[prerequisites[i].second] == true && post[prerequisites[i].second] == -1) return false;//有回边else if (isVisited[prerequisites[i].second] == false) {if (!dfs(prerequisites[i].second, prerequisites)) return false;}}}post[nowNode] = clock++;result.push_back(nowNode);return true;}vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {result = vector<int>();isVisited = vector<bool>(numCourses, false);//标记是否访问过pre = vector<int>(numCourses, -1);post = vector<int>(numCourses, -1);clock = 0;vector<int> toVisited;//源集合bool flag = true;vector<bool> hasIn(numCourses, false);//判断找出源for (int i = 0; i < prerequisites.size(); i++) {hasIn[prerequisites[i].second] = true;}for (int i = 0; i < hasIn.size(); i++) {if (hasIn[i] == false) toVisited.push_back(i);}if (toVisited.empty()) flag = false;//没有源if (flag != false) {for (int i = 0; i < toVisited.size(); i++) {if (!dfs(toVisited[i], prerequisites)) {flag = false;break;}}}for (int i = 0; i < numCourses; i++) {//是否有把所有点遍历过if (!isVisited[i]) {flag = false;break;}}if (flag == false) return vector<int>();else return result;}};