2012-11-29 27 views
0

我試圖解決這個問題:http://olimpiada-informatica.org/?cmd=downloadE&pbm=velo101&ext=pdf這是西班牙語,但我會嘗試在這裏翻譯:TLE的BFS從多個來源

你即將降落在地球上,當你發現有人已經在着陸地帶釋放了一些Velociraptors。
着陸旅程具有矩形形狀。我們用點(.)標出一個空白點,一個V的肉食動物和一個#有障礙物的地方(你不能登陸它們)。
需要一秒鐘的時間才能到達另一個地點,但他們只能水平和垂直移動。
你被要求標記一個X這些地方,在其上着陸,你會最大限度地延長你的剩餘壽命。

我曾經做過一個算法,我拿伶盜龍屬的每個位置,並作出BFS上每一個位置,但我越來越TLE,這裏是我的代碼:

http://ideone.com/a6BVv3

#include <algorithm> 
#include <cstdio> 
#include <cstring> 
#include <queue> 
#include <utility> 
using namespace std; 

int cost[501][501],xx,yy,n,m; 
char mat[501][501]; 
bool visit[501][501],first = true; 

int a[] = {-1,0,0,1}, b[] = {0,-1,1,0}; 

void check(int x,int y,int level) { 
    cost[x][y] = level; 
    for(int i = 0; i < 4; ++i) { 
    xx = x + a[i]; 
    yy = y + b[i]; 
    if(0 <= xx and xx < n and 0 <= yy and yy < m and mat[xx][yy] == '.') { 
     if(!visit[xx][yy] or level + 1 < cost[xx][yy]) { 
     visit[xx][yy] = true; 
     check(xx,yy,level + 1); 
     } 
    } 
    } 
} 

int max() { 
    int r = -1; 
    for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(mat[i][j] == '.') r = max(r,cost[i][j]); 
    return r; 
} 

void show() { 
    if(!first) puts("---"); 
    int r = max(); 
    for(int i = 0; i < n; ++i) { 
    for(int j = 0; j < m; ++j) { 
     if(cost[i][j] == r) printf("X"); 
     else printf("%c",mat[i][j]); 
    } 
    puts(""); 
    } 
} 

int main() { 
    while(scanf("%d %d",&n,&m) == 2) { 
    queue<pair<int,int> > cola; 
    for(int i = 0; i < n; ++i) { 
     scanf("\n"); 
     for(int j = 0; j < m; ++j) { 
     scanf("%c",&mat[i][j]); 
     if(mat[i][j] == 'V') cola.push(make_pair(i,j)); 
     } 
    } 
    memset(cost,-1,sizeof cost); 
    memset(visit,0,sizeof visit); 
    while(!cola.empty()) { 
     pair<int,int> aux = cola.front(); 
     visit[aux.first][aux.second] = true; 
     check(aux.first, aux.second,0); 
     cola.pop(); 
    } 
    show(); 
    first = false; 
    } 
    return 0; 
} 

有誰知道我該如何改進算法?

編輯

好吧,我是能夠解決的問題,這裏是代碼,如果有人有興趣:

#include <algorithm> 
#include <cstdio> 
#include <cstring> 
#include <queue> 
#include <utility> 
using namespace std; 

int cost[501][501],n,m; 
char mat[501][501]; 
bool visit[501][501],first = true; 
queue<pair<int,int> > cola; 

int a[] = {-1,0,0,1}, b[] = {0,-1,1,0}; 

int max() { 
    int r = -1; 
    for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(mat[i][j] == '.') r = max(r,cost[i][j]); 
    return r; 
} 

void show() { 
    if(!first) puts("---"); 
    int r = max(); 
    for(int i = 0; i < n; ++i) { 
    for(int j = 0; j < m; ++j) { 
     if(cost[i][j] == r) printf("X"); 
     else printf("%c",mat[i][j]); 
    } 
    puts(""); 
    } 
} 

int main() { 
    int cont = 0,x,y,xx,yy,level; 
    while(scanf("%d %d",&n,&m) == 2) { 
    for(int i = 0; i < n; ++i) { 
     scanf("\n"); 
     for(int j = 0; j < m; ++j) { 
     scanf("%c",&mat[i][j]); 
     if(mat[i][j] == 'V') cola.push(make_pair(i,j)); 
     } 
    } 
    memset(cost,-1,sizeof cost); 
    memset(visit,0,sizeof visit); 
    while(!cola.empty()) { 
     int s_cola = cola.size(); 
     for(int i = 0; i < s_cola; ++i) { 
     x = cola.front().first, y = cola.front().second; 
     cola.pop(); 
     level = cost[x][y]; 
     for(int i = 0; i < 4; ++i) { 
      xx = x + a[i], yy = y + b[i]; 
      if(0 <= xx and xx < n and 0 <= yy and yy < m and mat[xx][yy] == '.') { 
      if(!visit[xx][yy] or level + 1 < cost[xx][yy]) { 
       visit[xx][yy] = true; 
       cost[xx][yy] = level + 1; 
       cola.push(make_pair(xx,yy)); 
      } 
      } 
     } 
     } 
    } 
    show(); 
    first = false; 
    } 
    return 0; 
} 

回答

1

你在做檢查的深度優先搜索整個圖表()。將它與main()中的循環集成起來,而不是試圖找到深度優先的最短路徑。