【发布时间】:2019-01-25 00:50:46
【问题描述】:
我已经实现了这段代码,使用dfs来检测一个图中是否有一个循环,如果有,也打印这个循环的顶点。如果有多个循环,只需打印您找到的第一个循环。但不知何故,OJ 告诉我它对于某些测试用例不够有效。关于如何提高这段代码的效率的任何想法?
我一直在努力思考如何改进这一点,但没有任何进展。我想也许我应该尝试使用 dfs 以外的其他算法?
# using python3
from collections import defaultdict
class Graph():
def __init__(self, V):
self.V = V
self.graph = defaultdict(list)
def add_edge(self, u, v):
self.graph[u].append(v)
def dfs_walk(self, u):
# List to contain the elements of a circle
list_circle = list()
# Mark visited vertexes
visited = list()
stack = [u]
while stack:
v = stack.pop()
visited.append(v)
# If already in list_circle, means there is a circle.
if v in list_circle:
return True, list_circle[list_circle.index(v):], visited
# If v is not in list_circle and it has neighbor, collect it in the list,
# go to next vertex. If it hasn't neighbor, check the left vertex
else:
# the next vertex is the first neighbor of this vertex
if len(self.graph[v]) > 0:
stack.extend(self.graph[v])
list_circle.append(v)
# Didn't find a circle in this round.
return False, list_circle, visited
def is_cyclic(self):
control = [-1] * self.V
for i in range(self.V):
if control[i] == -1:
flag, list_circle, visited = self.dfs_walk(i)
for x in visited:
control[x] = 0
if flag:
return True, list_circle
# Didn't find any circle in all rounds.
return False, list_circle
if __name__ == "__main__":
line = input().split()
V, E = int(line[0]), int(line[1])
# Initialize the graph
g = Graph(V)
for r in range(E):
row = input().split()
start, end = int(row[0])-1, int(row[1])-1
g.add_edge(start, end)
flag, list_circle = g.is_cyclic()
if flag:
print("YES")
print(" ".join(str(i+1) for i in list_circle))
else:
print("NO")
第一行是顶点数和边数。在第一行之后,每一行代表一条边(有向)。
输入:
3 3
1 2
2 3
3 1
输出:
是的
1 2 3
【问题讨论】:
-
如果代码正确,但只需要性能改进,应该在 Code Review 上,而不是在这里。请注意,尽管它们需要工作的完整代码。
-
你在这里有点重新发明轮子。您对使用图形库的解决方案感兴趣吗?
-
@wim 这是 OJ 任务,不允许使用库