算法练习(28):Course Schedule II

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

分析与思路:同样还是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;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值