[英]Running BFS to find shortest path from bottom to top of a graph
我正在嘗試解決一個有約束的任務:\\ $ 1 \\ le B,L,S \\ le 100 000 \\ $。 為此,我從圖形底部的每個邊緣使用BFS,然后運行BFS直到我們達到y=0
為止。 但是,在編譯器中運行代碼時,出現超時錯誤。 為什么會出現TLE錯誤,並且在傳遞的代碼中我做了哪些更改?
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int bfs(const vector< vector<int> > &g, pair<int, int> p)
{
queue <pair<pair<int, int>, int> > que;
vector< vector<bool> > vis(100000,vector<bool>(100000,false)); //visited
int x, y, k = 0; //k = distance
pair <pair<int, int>, int> next, start;
pair <int, int> pos;
start = make_pair(make_pair(p.first, p.second), 0);
que.push(start);
while(!que.empty())
{
next = que.front();
pos = next.first;
x = pos.first;
y = pos.second;
k = next.second;
que.pop();
if (y == 0) {
return k;
}
if((g[x+1][y] == 1) && (vis[x+1][y] == false))
{
que.push(make_pair(make_pair(x+1, y), k+1));
vis[x+1][y] = true;
}
if((g[x][y+1] == 1) && (vis[x][y+1] == false))
{
que.push(make_pair(make_pair(x, y+1), k+1));
vis[x][y+1] = true;
}
if((g[x-1][y] == 1) && (vis[x-1][y] == false))
{
que.push(make_pair(make_pair(x-1, y), k+1));
vis[x-1][y] = true;
}
if((g[x][y-1] == 1) && (vis[x][y-1] == false))
{
que.push(make_pair(make_pair(x, y-1), k+1));
vis[x][y-1] = true;
}
}
}
int main()
{
int B,L,S,x,y, shortestDist = 1234567;
cin >> B >> L >> S;
vector< pair <int, int> > p; //stones in the first row
vector< vector<int> > g(B, vector<int>(L,0));
for(int i = 0; i < S; i++)
{
cin >> y >> x;
g[y][x] = 1; // stone = 1, empty = 0
if(y == B-1)
p.push_back(make_pair(x, y));
}
for(int i=0;i<p.size();++i)
{
shortestDist = min(shortestDist,bfs(g,p[i]));
}
cout << shortestDist + 2 << "\n"; //add 2 because we need to jump from shore to river at start, and stone to river at end
return 0;
}
您的方法存在兩個問題,導致O(B *(B * L + S))的復雜性。
第一個問題是,如果整個第一行都充滿石頭,則在最壞的情況下運行bfs B次。 您有S塊石頭,每塊石頭最多有4個鄰居,因此每次調用bfs都會在O(S)中運行,但是您進行了B次,因此在某些情況下,您的算法將需要進行O(B * S)運算-我確信問題的作者會注意具有此運行時間的程序將超時(畢竟這些操作至少要執行10 ^ 10次操作)。
解決此問題的一種可能方法是使用隊列中第一行的所有石頭開始bfs。 通過向圖形添加新的頂點並將其連接到第一行的石頭,也可以達到多個起點。 由於要使用的數據結構,第二種方法實施起來並不容易。
這(數據結構)是您的第二個問題:您有S = 10 ^ 5個元素/頂點/石頭,但是使用B * L = 10 ^ 10個存儲單元。 大約2G內存! 我不知道此問題的內存限制是多少! 將其初始化B次會使您總共花費B * B * L次操作。
更好的方法是使用稀疏數據結構(如鄰接表) 。 但是請注意在O(S ^ 2)中填寫此數據結構-為O(SlogS)使用一個集合,或者為O(S)運行時間甚至使用unordered_set。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.