我正在学习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;
}
我相信这个算法O(m log n)
的时间复杂度。插入边缘所需的时间复杂度为 O(1)
。所以AFAIK,这是我们能做的最好的(也许?)。我不确定这是否是存储图表的最佳方式。任何更好,更快的方法来存储图表和建议来改善这一点都会很棒。
答案 0 :(得分:0)
这不是优化问题。在将它们放入rcMask
之后,您应该将您放入队列true
中的每个节点的访问权限设置为访问,否则您将在很长一段时间内重新访问某些节点。您将queue
放入队列但未将其访问权限设置为node
并将其延迟,直到您将该节点从队列中取出,然后将其访问权限设置为true
。那会发生什么?请考虑此图表true
,V={a,b,c,d}
。首先E={a->b, a->c, a->d, b->d, c->d}
将a
推入队列但未设置其访问者。然后b,c,d
将b
推送到队列,之后d
也将c
推送到队列。所以你的队列看起来像d
。所以你要三次访问q={d,d,d}
。这是一个非常小的案例,你可以看到大案例,这怎么会导致一个大问题。
这样的事情:
d