您的位置:首页 > 产品设计 > UI/UE

207. Course Schedule My SubmissionsQuestionEditorial Solution【M】【48】【vip】【再来一遍】

2016-05-26 13:30 423 查看
There are a total of n courses you have to take, labeled from
0
to
n
- 1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair:
[0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how
a graph is represented.
click to show more hints.
Hints:

This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining
the basic concepts of Topological Sort.
Topological sort could also be done via BFS.

Subscribe to see which companies asked this question

这道题等价于判断有向图里有没有环。

有向图:
主要有深度优先和拓扑排序2中方法

1、拓扑排序,如果能够用拓扑排序完成对图中所有节点的排序的话,就说明这个图中没有环,而如果不能完成,则说明有环。

2、可以用Strongly Connected Components来做,我们可以回忆一下强连通子图的概念,就是说对于一个图的某个子图,该子图中的任意u->v,必有v->u,则这是一个强连通子图。这个限定正好是环的概念。所以我想,通过寻找图的强连通子图的方法应该可以找出一个图中到底有没有环、有几个环。

3、就是用一个改进的DFS

刚看到这个问题的时候,我想单纯用DFS就可以解决问题了。但细想一下,是不能够的。如果题目给出的是一个无向图,那么OK,DFS是可以解决的。但无向图得不出正确结果的。比如:A->B,A->C->B,我们用DFS来处理这个图,我们会得出它有环,但其实没有。

我们可以对DFS稍加变化,来解决这个问题。解决的方法如下:

图中的一个节点,根据其C
的值,有三种状态:

0,此节点没有被访问过

-1,被访问过至少1次,其后代节点正在被访问中

1,其后代节点都被访问过。

按照这样的假设,当按照DFS进行搜索时,碰到一个节点时有三种可能:

1、如果C[V]=0,这是一个新的节点,不做处理

2、如果C[V]=-1,说明是在访问该节点的后代的过程中访问到该节点本身,则图中有环。

3、如果C[V]=1,类似于2的推导,没有环。 在程序中加上一些特殊的处理,即可以找出图中有几个环,并记录每个环的路径

拓扑排序


该DAG的拓扑序列为A B C D或者A C B D


而此有向图是不存在拓扑序列的,因为图中存在环路

二.拓扑序列算法思想

(1)从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之;

(2)从有向图中删去此顶点以及所有以它为开始的弧;

重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。

check2是通过的做法
主函数里的是拓扑排序
check1是超时的

class Solution(object):
def canFinish(self, numCourses, prerequisites):

n = numCourses
p = prerequisites
v = [0] * n
dic = {}
indegree = [0] * n

graph = [[] for i in xrange(n)]#[[]] * n
for i,j in p:
graph[i].append(j)

#print graph

def check2(cur):
if v[cur] == -1:
return False
if v[cur] == 1:#如果访问到这儿,后面的节点之前都已经访问过了,没问题,所以等于一个剪枝的过程
return True
v[cur] = -1
#l = dic.get(cur,[])
for j in graph[cur]:
if not check2(j):
return False
v[cur] = 1
return True

for i in xrange(n):
if not check2(i):
return False
return True

'''
def check(cur):
if v[cur] == 1:
return True
v[cur] = 1
l = dic.get(cur)
if l != None:
for i in l:
if check(i):
return True
v[cur] = 0
return False

for i in p:
dic[i[0]] = dic.get(i[0],[]) + [i[1]]
indegree[i[1]] += 1

q = []
for i in xrange(len(indegree)):
if indegree[i] == 0:
q += i,
#print q
while q != []:
node = q.pop()
for i,j in p:
#print i,j,node
if i == node:
indegree[j] -= 1
if indegree[j] == 0:
q += j,
#print indegree
return sum(indegree)  == 0
'''
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: