测试简单有向图的无效性

时间:2017-09-11 10:52:32

标签: python-3.x graph

为了测试简单有向图的无效性,我使用了深度优先搜索算法。在某些测试用例中,我的代码运行良好,但有时它的工作方式不正确。在线评判服务器告诉我“在某些情况下,你得到的答案不正确。”但我不知道它在哪种情况下失败了。测试用例是隐藏的。我的代码如下(用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个边缘)。

2 个答案:

答案 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)时间内确定是否已经访问过某个节点,这应该会处理所有输入。

P.S:如果它能解决你的问题,请将我的答案标记为正确。