[英]How to find if there's a cycle within selected nodes in a directed graph?(C++)
我目前正在解決在有向圖中查找由選定節點組成的循環的問題。
對於此處描述的實例:
在節點 1、2、3 內有一個循環,在 1、2、4 內沒有找到循環。我嘗試通過以下操作自己實現該算法:
我的實現如下(為每個選定的節點調用該函數,並且每次都初始化存儲訪問節點的數組)
bool hasLoop(const int startNode, const bool directions[][MAX_DOT_NUM], const int nodesLen, bool nodesVisited[], const int selectedNodes[], const int selectedNum){
nodesVisited[startNode] = true;
for(int i = 0; i < nodesLen; i++){ //loop through all nodes
if(withinSelected(i, selectedNodes, selectedNum) == false) continue; //check loop only for selected nodes
if(directions[startNode][i] == 1){ //connected and is within selected nodes
if(nodesVisited[i] == true){
return true;
}else{
if(hasLoop(i, directions, nodesLen, nodesVisited, selectedNodes, selectedNum)){
return true;
}
}
}
}
return false;
}
但是,此實現不適用於我正在使用的在線法官的所有測試數據。 我發現我的算法與深度優先搜索不同,深度優先搜索使用白色,灰色,黑色數組來存儲未訪問,已訪問或不需要訪問的節點,我想知道是否是導致問題的原因。
希望我能在您的幫助下找到導致此實現不適用於所有情況的錯誤! 非常感謝您閱讀本文!
編輯:這是一個有向圖! 抱歉。
編輯:非常感謝您的幫助! 我修改了我的實現,讓函數只有在找到指向函數啟動節點的節點時才返回 true。 這是我使用的在線法官接受的最終實現:
bool hasLoop(const int currentNode, const bool directions[][MAX_DOT_NUM], const int nodesLen, bool nodesVisited[], const int selectedNodes[], const int selectedNum, const int startNode){
// cout << currentNode << " -> ";
nodesVisited[currentNode] = true;
for(int i = 0; i < nodesLen; i++){
if(withinSelected(i, selectedNodes, selectedNum) == false) continue;
if(directions[currentNode][i] == 1){ //connected and is within selected nodes
if(nodesVisited[i] == true){
if(i == startNode) return true;
}else{
if(hasLoop(i, directions, nodesLen, nodesVisited, selectedNodes, selectedNum, startNode)){
return true;
}
}
}
}
return false;
}
您的實現是DFS ,但對於不創建循環的“側節點”將失敗:
考慮具有 3 個節點(A,B,C)
:
A
/ \
/ \
V V
B <---- C
你的算法會告訴圖形有一個循環,而事實上 - 它沒有!
您可以通過查找Strongly Connected Components並查看是否存在非平凡(大小> 1)組件來解決它。
另一種解決方案是使用拓撲排序- 當且僅當圖形有循環時才返回錯誤。
在這兩種解決方案中,您只將算法應用於包含“選定節點”的子圖。 兩種解決方案都是O(|V|+|E|)
時間和O(|V|)
空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.