课程表上有一些课,是必须有修学分的先后顺序的,必须要求在上完某些课的情况下才能上下一门。问是否有方案修完所有的课程?如果有的话请返回其中一个符合要求的路径,否则返回[].
例子1:
Input: 2, [[1,0]]
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
course 0. So the correct course order is [0,1].
例子2:
Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [0,2,1,3]
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
BFS思路:每次找入度为0的节点。
1、先建立图(邻接表)、和入度表。
2、循环n次(n为节点数),每次找到度为0 的节点(循环n次,从头开始找),加入path中,然后将其出度的节点的入度-=1(循环入度表)。
先是找到入度为0的节点:1 将1加入path中,然后是2,3节点的入度减去1,因为1已经被处理掉了。 此时度为0的节点是2,3。 将2,3加入path中,…… |
![]()
|
伪代码:
循环n次:
循环n次:
找入度为0的节点
将度为0节点加入path中
循环入度表:
将度为0节点的出度节点的入度节点-=1
代码:
from collections import defaultdict def BFS(n,arr): # n 为节点数,arr为【【u1,v1】,【u2,v2】……】,这里的u和v中,v是u的父节点。 if not arr: return -1 graph = defaultdict(list) indegree = defaultdict(int) path = [] for u , v in arr: graph[v].append(u) indegree[u] += 1 for i in range(n): zeroDegree = False for j in range(n): if indegree[j] == 0: zeroDegree = True break if not zeroDegree: return [] indegree[j] -= 1 path.append(j) for val in graph[j]: indegree[val] -= 1 return path n= 5 arr = [[1,0],[2,0],[3,1],[3,2],[4,0]] print(BFS(n,arr))
DFS思路:递归
1、建立图
2、循环n次,每次是遍历一个节点是否已经visited且合法地加入path中了,如果False不合法则直接返回【】。
3、遍历一个节点时会将其后面的所有子节点都处理掉。
如,先是1,将1进行dfs处理【path中加入1,2,4,8,5】 然后是2,将2进行dfs处理,已经visited过了,继续循环 然后是3,将3进行dfs处理,没有visited,unkown状态,【path=【1,2,4,8,5】中加入【3,6,7】】 然后是4……,后面都是visited过的,都直接跳过。 |
![]() |
代码:
from collections import defaultdict def findPath(n,arr): if n == 0: return [] graph = defaultdict(list) for u , v in arr: graph[v].append(u) # 0为Unkown,1为visiting,2为visited path = [] visited = [0] * n for i in range(n): if not DFS(graph,visited,path,i): return [] return path def DFS(graph,visited,path,i): ####i节点:其正在遍历,但它的子节点的子节点也是它,表示产生了有环,则return FALSE if visited[i] == 1: return False ####i节点 :已经遍历过,后面已经没有节点了,return true elif visited[i] == 2:return True ####表示正在遍历i节点 visited[i] = 1 for j in graph[i]: if not DFS(graph,visited,path,j): return False path.append(i) visited[i] = 2 return True n = 5 arr = [[1,0],[2,0],[3,1],[3,2],[4,0]] print(findPath(n,arr))
已经给出了某些变量的比值,求新的变量的比值。如果这个变量没有出现过,或者不可到达,那么返回-1.
DFS思路:
1、建立图 {a:{b : 2.0} 、b:{a:1 /2.0,c:3.0}、c:{b:1/3.0}}
2、不在图中则返回-1
3、在图中,x == y,返回1,x != y,返回x到y的拓扑排序的权重相乘值。
代码:
from collections import defaultdict def solveque(arr ,values , que): if not arr: return [-1] * len(que) if not que: return [] graph = defaultdict(dict) for (x,y) , value in zip(arr,values): graph[x][y] = value graph[y][x] = 1/value if value else 0 for x,y in que: if x in graph and y in graph: return dfs(graph,x,y,set()) else: return -1.0 def dfs(graph,x,y,visited): if x == y: return 1.0 visited.add(x) for k in graph[x]: if k in visited:continue visited.add(k) d = dfs(graph,k,y,visited) if d > 0: return d*graph[x][k] return -1.0 arr = [[‘a‘,‘b‘],[‘b‘,‘c‘]] values = [2.0,3.0] que = [[‘a‘,‘c‘],[‘a‘,‘v‘]] print(solveque(arr ,values , que))
原文:https://www.cnblogs.com/Lee-yl/p/10500569.html