[英]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.