簡體   English   中英

測試簡單有向圖的非循環性

[英]Testing acyclicity of simple directed 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 Saryheni的建議,我修復了在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條邊)。

我不是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。節點1的DFS函數將返回值0,而不是完成運行從節點3開始的DFS,並找到一個周期。

更新:此測試用例在您更新的代碼上失敗:

1

3 3
1 2
1 3
2 3

正確的輸出為1 ,而您的代碼顯示-1 嘗試調試該測試用例,以在代碼中找到問題。

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:

每次,您都遍歷整個列表以查找是否已訪問節點。 對於dfs每個單個遞歸調用,大多數情況下為O(n) 相反,您應該維護一個boolean visited array以便可以確定節點是否已在O(1)時間內訪問過,這應該處理所有輸入。

PS:如果可以解決您的問題,請標記我的回答正確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM