[英]Detect cycle in an undirected graph
In order to detect cycle in undirected graph, following code anf algorithm are given;为了检测无向图中的循环,给出了以下代码anf算法; I am using normal Breadth First traversal along with slight modifications:
我正在使用正常的广度优先遍历以及轻微的修改:
void bfsUtil(int s,vector<bool> &visited,vector<int> adj[],vector<int> &visits) {
queue<int> q;
q.push(s);
visits[s]++;
visited[s]=true;
while(!q.empty()) {
int vertex=q.front();
q.pop();
for(int i=0;i<adj[vertex].size();i++) {
if(!visited[adj[vertex][i]]) {
visited[adj[vertex][i]]=true;
q.push(adj[vertex][i]);
visits[adj[vertex][i]]++;
} else {
visits[adj[vertex][i]]++;
}
}
}
}
/* This function is used to detect a cycle in undirected graph
* adj[]: array of vectors to represent graph
* V: number of vertices
*/
bool isCyclic(vector<int> adj[], int V)
{
vector<int> visits(V,0);
vector<bool> visited(V,false);
for(int i=0;i<V;i++){
if(!visited[i]) {
bfsUtil(i,visited,adj,visits);
}
}
for(int i=0;i<visits.size();i++) {
if(visits[i]>2) {
return true;
}
}
return false;
}
Algorithm:
1. Normal Breadth first search and maintaining a count aray for the no of visits of each vertex.
2. If no of visits>2
print cycle is present
else
print no cycle
But i am getting wrong anwer for below test case:但是对于以下测试用例,我的回答是错误的:
Input:
46 45
0 44 1 23 1 35 1 37 1 38 2 20 2 35 3 13 4 44 5 21 5 36 6 41 7 8 8 18 9 17 9 41 9 45 10 13 10 21 10 33 10 34 10 39 10 42 11 17 12 24 13 44 14 19 15 25 16 34 18 24 19 25 21 24 21 26 22 37 23 28 25 31 25 35 25 40 25 41 25 44 27 43 27 44 29 40 30 34 32 33
Its Correct output is:
0
And Your Code's output is:
1
Where is my algorithm going wrong?我的算法哪里出错了?
Your algorithm is wrong.你的算法是错误的。 consider a graph of the following edges:
考虑以下边的图:
0 - 1
0 - 2
When the current node is 1, it also checks 0 as there is an edge from 1 to 0 too.当当前节点为 1 时,它也检查 0,因为从 1 到 0 也有一条边。 so it will increment the visits count of 0. Similarly, 2 will also increment the count.
所以它将增加访问计数 0。同样,2 也会增加计数。 So your code will always detect cycles wrongly.
所以你的代码总是会错误地检测周期。
To resolve this, you should keep a parent node for each node, from where the node is visited.要解决此问题,您应该为每个节点保留一个父节点,从该节点访问该节点。 When you are checking, you should never consider the edge to the parent.
当你检查时,你永远不应该考虑父母的优势。 And finally, you don't need the visits array.
最后,您不需要访问数组。 If you find an adjacent node that is not parent of current node, but is still visited before, then you can conclude that there is a cycle.
如果发现相邻节点不是当前节点的父节点,但之前仍然访问过,则可以断定存在循环。
Modifying your code:修改您的代码:
bool bfsUtil(int s,vector<bool> &visited,vector<int> adj[],vector<int> &parent) {
queue<int> q;
q.push(s);
visited[s]=true;
while(!q.empty()) {
int vertex=q.front();
q.pop();
for(int i=0;i<adj[vertex].size();i++) {
if(adj[vertex][i] == parent[vertex])
continue;
if(!visited[adj[vertex][i]]) {
visited[adj[vertex][i]]=true;
q.push(adj[vertex][i]);
parent[adj[vertex][i]] = vertex;
} else {
//cycle detected;
return true;
}
}
}
return false;
}
/* This function is used to detect a cycle in undirected graph
* adj[]: array of vectors to represent graph
* V: number of vertices
*/
bool isCyclic(vector<int> adj[], int V)
{
vector<bool> visited(V,false);
vector<int> parent(V, -1); // -1 means no parent assigned
for(int i=0;i<V;i++){
if(!visited[i]) {
if(bfsUtil(i,visited,adj,parent)) return true;
}
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.