簡體   English   中英

在有向圖中查找所有其他節點均可訪問的節點

[英]Find nodes in directed graph that is reachable from all other nodes

問題:

給定 N 個節點和 M 個邊的有向圖 (M <= 2.N)。 查找所有其他節點可訪問的所有節點。

例子:

下圖有 4 個節點和 4 個邊:

在此處輸入圖片說明

答:節點(2)(3)可從所有其他節點到達。

附:

我想出的唯一解決方案是還原圖形,BFS 所有節點並檢查它們是否到達所有其他節點。 但這需要 O(n^2)。

有沒有其他方法需要 O(n.logn) 或更少?

這是我對 O(n^2) 方法的看法:

void init(){
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v; cin >> u >> v;
        adj[v].emplace_back(u);
    }
}

void dfs(int u){
    visited[u] = true;
    for(int v : adj[u])
        if(!visited[v]) dfs(v);
}

init();
for(int u = 1; u <= n; u++){
    memset(visited, 0, sizeof visited);
    dfs(u);
    if(count(visited + 1, visited + n + 1, 1) == n) cout << u << ' ';
}

你能分享那個需要O(n^2)嗎?

無論如何,這種方法只需要 O(n),這比 O(n log n) 更好!

 class DirectedGraph { graph = {} constructor(directedGraph) { for (let [id, arrow] of directedGraph) this.graph[id] = { arrow, isVisited: false } } find_end_points(id) { let out = [], graph = this.graph; function go_next(id, from) { let node = graph[id]; if (node.isVisited || !node.arrow) return out.push(id) if (node.arrow == from) out.push(id); node.isVisited = true; go_next(node.arrow, id); } go_next(id, null); return out } } let directedGraph = new DirectedGraph([[2, 3], [3, 2], [1, 2], [4, 1]]); console.log(directedGraph.find_end_points(4))

您可以使用Tarjan 的強連通分量算法獲得 O(|V| + |E|) 算法。 許多示例實現可在線或在標准算法教科書中獲得。

一旦你有了強連通分量,所有其他節點可達的頂點集合正是其強連通分量的出度為 0(圖中的匯)的頂點集合。 但是,有一個例外:如果圖的凝聚(由強連通分量引起的新圖)不連通,則不存在這樣的頂點。 您可以通過從任何入度為 0 的頂點運行廣度優先搜索,在 O(|V|) 時間內測試有向無環圖的連通性。

暫無
暫無

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

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