BFS遍历图节点两次
BFS traverses graph node twice
我在我的这段代码中发现了一个错误,其中图中的一个节点出现了两次。我用矢量来存储边之间的关系。非常感谢您的帮助。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
vector<int> v[n+1];
for (int i = 0; i < m; ++i)
{
int a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
std::queue<int>q ;
q.push(1);
cout<<"And the traversal is:n";
bool visited[n+1]={false};
for(;!q.empty();){
int curr=q.front();
q.pop();
cout<<curr<<endl;
for(int i=0;i<v[curr].size();++i){
if(!visited[v[curr][i]]){
q.push(v[curr][i]);
visited[curr]=true;
}
}
}
}
我检查的输入:
5 5
1 3
3 2
2 4
3 5
5 4
输出:
And the traversal is:
1
3
2
5
4
4
您需要区分节点可能处于的三种状态:
- 未处理(尚未看到)
- 已发现(已排队)
- 已处理(遍历、输出)
使用visited
布尔数组,您可以在发现节点或遍历节点时对其进行标记。虽然术语"已访问"通常指的是后者,但使用前者意味着节点不会多次添加到队列中,也不需要额外的if (visited[curr]) continue;
检查。
因此,要做到这一点,您需要在代码中修复两件事:
- 初始化队列的起始节点(
1
)已被定义发现 - 在当前节点的邻居的循环中,当您将
visited[curr]
添加到队列中时,您不能将其标记为"已发现",而必须将它标记为"发现">
cout<<"And the traversal is:n";
std::queue<int>q;
bool visited[n+1]={false};
q.push(1);
visited[1] = true;
while(!q.empty()){
int curr=q.front();
q.pop();
cout<<curr<<endl;
for(int i=0;i<v[curr].size();++i){
int target = v[curr][i]; // opposite node on edge
if(!visited[target]){
q.push(target);
visited[target]=true;
}
}
}
下面的旧(不完整)答案您希望将curr
ent节点设置为visited
始终,而不仅仅是当它有一个尚未访问的邻居时(4实际上没有任何邻居)。将其移出循环:
for(int i=0;i<v[curr].size();++i){
if(!visited[v[curr][i]]){
q.push(v[curr][i]);
}
}
visited[curr]=true;
也许你甚至应该把它移到循环的前面,以防出现自循环边
相关文章:
- 有什么方法可以遍历结构吗
- 在循环中按顺序遍历成员变量
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- 如何遍历几个每小时一次的根(.root)文件,并将它们组合成更大的每日数据.root文件?
- 如果你有一个固定大小的数组,你需要遍历它!n次,使用二进制搜索如何改变时间复杂性
- 如何遍历具有两个节点的链接节点
- 图论 - 从顶点 A 开始,遍历两个方向的所有路径,最后以最短的方式再次到达 A
- 使用两种不同的方法遍历 Vector 的结果不一致
- 如何在 c++ 中多次遍历链表
- 一次遍历 8 个向量字节并执行按位运算
- BFS遍历图节点两次
- 遍历目录中两个文件对
- 同时遍历两个 std::lists
- 如何遍历整个字符串并一次播放一个字符C++
- 无法遍历树 - 节点被重新遍历了大量次,但仍然是非循环的
- 如何遍历两对 STL 集中的所有元素<对<t1,t2>,pair<t1,t2>>?
- 使用相同的迭代器循环遍历两个 std::vector
- 如何在一次遍历中近似数组中不同值的计数
- 如何遍历两个类似stl的容器(笛卡尔积)
- 有没有一种优雅的方法来遍历两个映射并比较值(映射具有相同的类型)