优化BFS的实施
Optimizing an implementation of BFS
我正在学习Graph的基础知识,并从
开始解决问题https://www.hackerrank.com/challenges/bfsshortreach.代码运行良好,但我得到了一个测试用例的TLE。我把cin/cout改成了printf/scanf,希望它能被接受,但没有成功。到目前为止,我的代码是
#include <iostream>
#include <queue>
#include <climits>
#include <stdio.h>
#include <queue>
#include <list>
#include <vector>
struct Graph
{
int size;
std::list<int> *adj;
};
Graph* createGraph(int size)
{
Graph *graph = new Graph();
graph->size = size;
graph->adj = new std::list<int>[size];
return graph;
}
void addEdge(Graph *graph, int source, int dest)
{
graph->adj[source].push_back(dest);
graph->adj[dest].push_back(source);
}
void printGraph(Graph *graph)
{
for (int i = 0; i < graph->size; ++i)
{
for(std::list<int>::iterator it = graph->adj[i].begin(); it!= graph->adj[i].end(); ++it)
{
std::cout<<*it<<' ';
}
std::cout<<std::endl;
}
}
void BFS(Graph *graph, int src)
{
std::queue <int> nodes;
std::vector<bool> v(graph->size,false);
std::vector<int> distance(graph->size, INT_MAX);
v[src] = true;
distance[src] = 0;
nodes.push(src);
std::list<int>::iterator it;
while(!nodes.empty())
{
int temp = nodes.front();
v[temp] = true;
nodes.pop();
for(it = graph->adj[temp].begin(); it!= graph->adj[temp].end(); ++it)
{
if(!v[*it])
{
nodes.push(*it);
int current = distance[temp] != INT_MAX? distance[temp] : 0;
distance[*it] = std::min(current + 6, distance[*it]);
}
}
}
for (int i = 0; i < distance.size(); ++i)
{
int dist = distance[i] != INT_MAX ? distance[i] : -1;
if(i!= src)
{
printf("%d ", dist);
}
}
printf("n");
}
int main(int argc, char const *argv[])
{
int T;
scanf(" %d", &T);
while(T--) {
int n, m, s;
// cin>>n>>m;m
scanf(" %d %d", &n, &m);
Graph *graph = createGraph(n);
while(m--)
{
int x, y;
// cin>>x>>y;
scanf(" %d %d", &x, &y);
addEdge(graph, x-1, y-1);
}
// cin>>s;
scanf(" %d", &s);
BFS(graph, s-1);
// printGraph(graph);
}
return 0;
}
我相信CCD_ 1。并且插入边所需的时间复杂度是 O(1)
。所以AFAIK,这是我们能做的最好的事情(也许?)。我不确定这是否是存储图形的最佳方式。任何更好、更快的存储图形的方法和改进建议都将非常棒。
这不是优化的问题。您应该在将队列true
中的每个节点放入queue
后立即设置它们的visited,否则您将多次重新访问某些节点。您将一个node
放入队列中,但没有将其"已访问"设置为true
,并将其延迟到将该节点从队列中取出,然后将其"访问"设置成true
。那么会发生什么呢?考虑这个图V={a,b,c,d}
,E={a->b, a->c, a->d, b->d, c->d}
。第一个CCD_ 10在队列中推送CCD_。然后O(m log n)
2将d
推送到队列,之后c
也将d
推送到队列。所以您的队列看起来像q={d,d,d}
。因此,您将访问d
三次。这是一个非常小的案例,你可以看到,对于大的案例,这怎么会导致一个大问题。
类似这样的东西:
queue <int> q;
q.push(source);
visited[source] = true;
while ( q.size() ){
int current_node = q.front();
q.pop();
for ( int i=0; i<adjacencyList[current_node].size(); ++i ){
int next_node = adjacencyList[current_node][i];
if ( visited[next_node] )
continue;
dist[next_node] = dist[current_node] + 1;
visited[next_node] = 1;
q.push(next_node);
}
}
相关文章:
- 空基优化子对象的地址
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 返回值优化:显式移动还是隐式
- 人脸跟踪arduino代码的优化
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 如何用C++编写BFS函数
- 纯函数,为什么没有优化
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 如何以优化的方式同时迭代两个间距不相等的数组
- 使用 bfs 解决连接组件问题时得到错误的答案
- 小字符串优化(调试与发布模式)
- 浮点定向舍入和优化
- Visual Studio 调试优化如何工作?
- 为什么开关的优化方式与 c/c++ 中的链接不同?
- 线性优化目标函数中的绝对值
- GCC 会优化内联访问器吗?
- gcc 如何优化此循环?
- 优化BFS的实施