[英]DFS algorithm to detect cycles in graph
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class Graph{
public:
vector<int> adjList[10001];
void addEdge(int u,int v){
adjList[u].push_back(v);
adjList[v].push_back(u);
}
};
bool dfs(Graph graph, int n){
vector<int> neighbors;
int curr,parent;
bool visited[10001] = {0};
stack<int> s;
//Depth First Search
s.push(1);
parent = 0;
while(!s.empty()){
curr = s.top();
neighbors = graph.adjList[curr];
s.pop();
//If current is unvisited
if(visited[curr] == false){
for(int j=0; j<neighbors.size(); j++){
//If node connected to itself, then cycle exists
if(neighbors[j] == curr){
return false;;
}
else if(visited[neighbors[j]] == false){
s.push(neighbors[j]);
}
//If the neighbor is already visited, and it is not a parent, then cycle is detected
else if(visited[neighbors[j]] == true && neighbors[j] != parent){
return false;
}
}
//Mark as visited
visited[curr] = true;
parent = curr;
}
}
//Checking if graph is fully connected
for(int i=1; i<=n; i++){
if(visited[i] == false){
return false;
}
}
//Only if there are no cycles, and it's fully connected, it's a tree
return true;
}
int main() {
int m,n,u,v;
cin>>n>>m;
Graph graph = Graph();
//Build the graph
for(int edge=0; edge<m; edge++){
cin>>u>>v;
graph.addEdge(u,v);
}
if(dfs(graph,n)){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
return 0;
}
我試圖確定給定圖是否為樹。
我執行DFS並查找周期,如果檢測到周期,則給定的圖不是樹。
然后我檢查是否所有節點都已訪問過,如果沒有訪問過任何節點,則給定圖不是樹
輸入的第一行是:nm然后是m行,它們表示連接兩個節點的邊
n是節點數m是邊數
輸入示例:
3 2
1 2
2 3
這是一個SPOJ問題, 網址為http://www.spoj.com/problems/PT07Y/ ,我得到了錯誤的答案。 但是根據我的說法,DFS似乎是正確的。
因此,我針對注釋中的一些簡單測試用例檢查了您的代碼,看來對於
7 6
3 1
3 2
2 4
2 5
1 6
1 7
您的答案為“是”,而程序給出“否”。
在這種情況下,鄰居就是這樣:
1: 3 6 7
2: 3 4 5
3: 1 2
4: 2
5: 2
6: 1
7: 1
所以,當你訪問1你推3
, 6
, 7
堆棧。 您的父母被設置為1
。 一切都很好。
您從堆棧中彈出7
,您不將任何內容壓入堆棧,並且清除了循環檢查,因此當您退出while循環時,您將visited[7]
設置為true
,並將父級設置為7
(!!!!!)。
在這里,您可以看到運行不順利,因為從堆棧中彈出6
后,您已將7
保存為parent
。 它應該是1
。 這將使neighbor[0] != parent
循環檢查失敗。
我建議在映射數組中添加保留父對象,並通過應用union-merge檢測周期。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.