BFS 使用不正确

Posted

技术标签:

【中文标题】BFS 使用不正确【英文标题】:Incorrect BFS usage 【发布时间】:2020-06-19 19:18:51 【问题描述】:

嘿,所以我正在学习 BFS,我想用它来知道从一个点到另一个点的距离,以便我的程序进行扫描

0 2 4
0 3 6
0 5 7
0 4 8
2 1 6
5 6 1
start, end, distance.

它应该告诉我从 0 到 1 到 2 到 3 的距离等等

所以在这个例子中,从 0 到 1 的距离是 10,因为从 0-2 的距离是 4,从 2-1 的距离是 6。

但我的程序在编译时说:在抛出 'std::bad_alloc' 的实例后调用终止 什么():std::bad_alloc

我希望你能帮我修复它,这样它才能正常工作。谢谢。

 #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector<long long> vi;
typedef pair<long long,long long> pi;
typedef vector<pi> vpi;

#define FOR(i, a, b) for(ll i=ll(a); i<ll(b); i++)
#define ROF(i, a, b) for(ll i=ll(a); i>=ll(b); i--)
#define f first
#define s second
#define pb emplace_back
#define mp make_pair
#define SQ(a) (a)*(a)
#define all(a) (a).begin(), (a).end()

vector<pair<int,int> >adjacency_list[6];
bool visited[7];
int dist[7]=-1;
int main() 

dist[0]=0;
visited[0]=1;

for(int i=1;i<=6;i++)
  int a,b,c;
  cin>>a>>b>>c;
  adjacency_list[a].pb(mp(b,c));
    adjacency_list[b].pb(mp(a,c));


queue<int>q;

q.push(0);

while(!q.empty())
  int current=q.front();
  q.pop();

for(auto i=adjacency_list[current].begin();i!=adjacency_list[current].end();i++)
if(!visited[i->first])
  q.push(i->first);
  dist[i->first]=dist[current]+i->second;
  visited[i->first]= true;
  
 



for(int i=0;i<7;i++)
  cout<<i<<' '<<dist[i]<<endl;


 return 0;

【问题讨论】:

首先,不要使用#include 或使用命名空间std。其次,当您初始化 dist[] 时,请记住您只将第一个元素(而不是所有元素)初始化为 -1。 并删除宏。你的SQ 宏会为int x = 0; SQ(x++); 生成什么?请阅读此主题:***.com/a/14041847/8802609 嘿,但我不知道您是否可以提供一些解决问题的代码,因为我已经尝试过您的建议,但无法使其正常工作。 【参考方案1】:

adjacency_list 有 6 个元素,但 adjacency_list[b] 中的 b 最多可以有 6 个元素,因此您的程序具有未定义的行为。

我通过替换代码中所有不必要的typedefs、#defines 和非标准#incldues 发现这一点,用std::array 替换原始数组,然后用at 替换[],这将检测到越界访问:

#include <vector>
#include <utility>
#include <iostream>
#include <queue>
#include <array>

std::array<std::vector<std::pair<int, int> >, 6> adjacency_list;
std::array<bool, 7> visited;
std::array<int, 7> dist =  -1 ;
int main() 

    dist.at(0) = 0;
    visited.at(0) = 1;

    for (int i = 1; i <= 6; i++) 
        int a, b, c;
        std::cin >> a >> b >> c;
        adjacency_list.at(a).emplace_back(b, c);
        adjacency_list.at(b).emplace_back(a, c);
    

    std::queue<int>q;

    q.push(0);

    while (!q.empty()) 
        int current = q.front();
        q.pop();

        for (auto i = adjacency_list.at(current).begin(); i != adjacency_list.at(current).end(); i++) 
            if (!visited.at(i->first)) 
                q.push(i->first);
                dist.at(i->first) = dist.at(current) + i->second;
                visited.at(i->first) = true;
            
        
    

    for (int i = 0; i < 7; i++) 
        std::cout << i << ' ' << dist.at(i) << "\n";
    

    return 0;

【讨论】:

以上是关于BFS 使用不正确的主要内容,如果未能解决你的问题,请参考以下文章

正确性证明:图论中树的直径算法

Acwing 179 八数码问题 (bfs or A*)

最短路径:DFS、BFS 还是两者兼而有之?

LeetCode1293网格中的最短路径(DFS和BFS)分析

如果边没有按权重排序的顺序插入双端队列,0-1 BFS 会产生正确的答案吗?

两次bfs求树的直径的正确性