为了测试简单有向图的无效性,我使用了深度优先搜索算法。在某些测试用例中,我的代码运行良好,但有时它的工作方式不正确。在线评判服务器告诉我“在某些情况下,你得到的答案不正确。”但我不知道它在哪种情况下失败了。测试用例是隐藏的。我的代码如下(用Python3编写)。
def get_graph():
graph = {}
numofn, numofe = map(int, input().split())
for i in range(1, numofn+1):
graph[i] = []
for i in range(numofe):
s, e = map(int, input().split())
graph[s].append(e)
return graph
def dfs(v, visited, graph):
"""
input: current vertex v and list of visited node and graph
output: if acyclic 0 else 1
"""
if v in visited:
return 1
visited.append(v)
for next in graph[v]:
return dfs(next, visited, graph)
return 0
def test_acyclicity(graph):
"""
input: graph
output: 1 if acyclic else -1
"""
for s in graph.keys():
if dfs(s, [], graph) == 1:
return -1
return 1
if __name__ == "__main__":
N = int(input())
for i in range(N):
input()
graph = get_graph()
if i == N-1:
print(test_acyclicity(graph))
else:
print(str(test_acyclicity(graph)) + " ", end='')
预期的投入在这里。
3
2 1
1 2
4 4
4 1
1 2
2 3
3 1
4 3
4 3
3 2
2 1
有3个测试用例(前3个表示“有3个测试用例。”),并遵循这种格式。
|V| |E|
(list of non-weighted directed edges)
...
输入正如这样假设:顶点是[1,2,3,..,| E |]。
输出:
1 -1 1
所以在这种情况下,我的程序运行良好。但是判断服务器告诉我它失败了。
我的问题是“在哪种情况下我的程序失败了?”。
后记
根据Said Sryheni的建议,我在我的dfs搜索中修复了我的错误。
def dfs(v, visited, graph):
"""
input: current vertex v and list of visited node and graph
output: if acyclic 0 else 1
"""
if v in visited:
return 1
visited.append(v)
for next in graph[v]:
ret = dfs(next, visited, graph)
if ret == 1:
return 1
return 0
这适用于一些小的测试用例,但它总是在一些大的测试用例中返回(例如图表有1000个节点和1000个边缘)。
答案 0 :(得分:0)
我不是python的专家,但在你的dfs函数中,在这一行:
for next in graph[v]:
return dfs(next, visited, graph)
这不会仅返回第一个孩子的价值吗?我的意思是想象下面的测试用例:
1
3 3
1 2
1 3
3 1
在这种情况下,您的代码将从编号为1
的节点启动DFS,转到2
,看到节点编号2
没有更多子节点并返回0. DFS节点1
上的函数将返回值0,而不是从节点3
开始运行DFS,并找到一个循环。
<强>更新强> 此测试用例在您更新的代码上失败:
1
3 3
1 2
1 3
2 3
正确的输出为1
,而您的代码则打印-1
。尝试调试此测试用例以在代码中找到问题。
答案 1 :(得分:0)
def dfs(v, visited, graph):
"""
input: current vertex v and list of visited node and graph
output: if acyclic 0 else 1
"""
if v in visited:
return 1
visited.append(v)
for next in graph[v]:
return dfs(next, visited, graph)
return 0
在上述方法中,错误在于:
if v in visited:
每次,您都要遍历整个列表,以查明是否已访问过某个节点。对于O(n)
的每次递归调用,这通常是dfs
。相反,您应该维护一个boolean visited array
,这样您就可以在O(1)
时间内确定是否已经访问过某个节点,这应该会处理所有输入。