leetcode 207. Course Schedule (medium) 有向图

题目链接


思路:
题目可以转换成检测一个有向图是否有环。

解法一:
深度搜索
利用着色法,对每一个节点都遍历,同时有三种遍历状态:0 未被访问,1 正被访问,2 已被访问
若在遍历时遇到正被访问的节点,说明有环。

class Solution
{
public:
	vector<vector<int>> graph;
	vector<int> color; // 0 未被访问,1 正被访问,2 已被访问
	bool canFinish(int numCourses, vector<vector<int>> &prerequisites)
	{
		graph.resize(numCourses);
		color.assign(numCourses, 0);
		// 构建图
		for (auto &edge : prerequisites)
			graph[edge[1]].push_back(edge[0]);
		// 搜索
		for (int i = 0; i < numCourses; i++)
		{
			if (color[i] == 0)
				if (!dfs(i))
					return false;
		}
		return true;
	}
	bool dfs(int ind)
	{
		if (color[ind] == 2)
			return true;
		color[ind] = 1;
		for (auto v : graph[ind])
		{
			if (color[v] == 2)
				continue;
			if (color[v] == 1)
				return false;
			//if (color[v] == 0)
			if (!dfs(v))
				return false;
		}
		color[ind] = 2;
		return true;
	}
};

解法二:
拓扑排序
重复寻找入度为0的顶点,并将该顶点从图中删除,及其连接的所有出点入度减1,最终若图中仍存在入度为1的结点,说明有回路。

class Solution
{
public:
	vector<vector<int>> graph;
	vector<int> degree;
	bool canFinish(int num, vector<vector<int>> &pre)
	{
		graph.resize(num);
		degree.assign(num, 0);
		// 构建图
		for (auto &edge : pre)
		{
			graph[edge[1]].push_back(edge[0]);
			++degree[edge[0]];
		}
		// 存储所有入口点
		queue<int> que;
		for (int i = 0; i < num; i++)
			if (degree[i] == 0)
				que.push(i);

		while (!que.empty())
		{
			int cur = que.front();
			que.pop();
			--num;
			for (auto next : graph[cur])
			{
				if (--degree[next] == 0)
					que.push(next);
			}
		}
		return num == 0;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值