📅  最后修改于: 2023-12-03 15:42:18.132000             🧑  作者: Mango
这道题目是关于图(Graph)的基本操作和算法。
给定一个有向无环图(DAG),这个图有$n$个节点,我们要对这个图进行以下操作:
对于这道题目,我们可以使用深度优先搜索(DFS)和拓扑排序(Topological Sort)来解决。
对于操作1,我们可以从节点$s$开始深度优先遍历整个图,记录所有可以到达的节点。在遍历时,我们可以使用一个布尔型数组$visited$来记录每一个节点是否已经被访问过。
对于操作2,我们可以从节点$s$开始深度优先遍历整个图,记录所有路径。在遍历时,我们可以使用一个栈$stack$来保存走过的路径,每次发现目标节点$t$时,将栈中的路径记录下来。
这种方法的时间复杂度为$O(n+m)$,其中$m$为边的数量。
对于操作1和操作2,我们可以使用拓扑排序来解决。
对于操作1,我们可以先对图进行拓扑排序,然后从节点$s$开始向下遍历,将所有没有出边的节点依次加入到答案中,如果遇到一个节点存在出边,则把它的所有出边指向的节点加入到答案中。这样我们就可以得到所有可以到达的节点集合。
对于操作2,我们可以先对图进行拓扑排序,然后使用动态规划的思想进行求解。我们可以使用一个$dp[i]$数组表示从节点$s$到节点$i$的所有路径,初始化为一个空的二维数组。然后对于两个相邻的节点$i$和$j$,如果存在一条从$i$到$j$的边,那么我们就可以将$dp[j]$数组中的所有路径加上$i$到$j$的这条边,具体的操作可以采用类似DFS的方法。
这种方法的时间复杂度为$O(n+m)$,其中$m$为边的数量。
def dfs1(node, visited, graph, ans):
visited[node] = True
ans.add(node)
for next_node in graph[node]:
if not visited[next_node]:
dfs1(next_node, visited, graph, ans)
def get_reachable_nodes_dfs(s, graph):
n = len(graph)
visited = [False]*n
ans = set()
dfs1(s, visited, graph, ans)
return ans
def dfs2(node, visited, graph, stack, ans, t):
visited[node] = True
stack.append(node)
if node==t:
ans.append(stack.copy())
else:
for next_node in graph[node]:
if not visited[next_node]:
dfs2(next_node, visited, graph, stack, ans, t)
stack.pop()
visited[node] = False
def get_all_paths_dfs(s, t, graph):
n = len(graph)
visited = [False]*n
stack = []
ans = []
dfs2(s, visited, graph, stack, ans, t)
return ans
def get_reachable_nodes_topo(s, graph):
n = len(graph)
indegree = [0]*n
ans = set()
for i in range(n):
for j in graph[i]:
indegree[j] += 1
q = [s]
while q:
node = q.pop()
ans.add(node)
for next_node in graph[node]:
indegree[next_node] -= 1
if indegree[next_node]==0:
q.append(next_node)
ans.add(next_node)
return ans
def get_all_paths_topo(s, t, graph):
n = len(graph)
indegree = [0]*n
dp = [[] for _ in range(n)]
for i in range(n):
for j in graph[i]:
indegree[j] += 1
dp[s] = [[s]]
q = [s]
while q:
node = q.pop()
for next_node in graph[node]:
indegree[next_node] -= 1
for path in dp[node]:
dp[next_node].append(path+[next_node])
if indegree[next_node]==0:
q.append(next_node)
return dp[t]
以上的代码只是伪代码,并不能直接运行。