通过多个点的最短路径[C ++]

时间:2015-01-27 18:42:03

标签: c++ breadth-first-search

给定一个网格,其中每个单元格的内容可以

X :"墙"

H :a" checkpoint" (最多5个)

G :起始位置(正好一个)

我必须找到从 G 开始覆盖所有检查点所需的最小移动次数( H )。个别移动可以是水平或垂直的,但可以通过组合水平和垂直移动来实现对角线移动。移出网格或墙壁( X )是不可能的。

对于网格

    ..H..
    ..X.H
    G...X

预期答案 7

网格中的行数和列数最多为20.

我尝试编写bfs代码来解决问题,但是当使用上面的网格进行测试时,会产生 6 ,这是不正确的。

我不知道自己做错了什么。有人可以帮忙吗?

#include <iostream>
#include &lt;bits/stdc++.h>
#include &lt;algorithm>
#include &lt;cstdio>
#include &lt;stdlib.h>
#include &lt;cmath>
#include &lt;cstring>
#include &lt;math.h>
#include &lt;string>
#include &lt;sstream>
#include &lt;vector>
#include &lt;iomanip>
#include &lt;deque>
#include &lt;queue>

#define loop(i, n) for(int i = 0; i < n; i++)  
#define scan(x) do{while((x=getchar())<'0'); for(x-='0'; '0' < (_=getchar());x=(x<<3)+(x<<1)+_-'0');}while(0)  
#define ull unsigned long long  

char _;

using namespace std;
typedef pair <int, int> ipair;

int rows, columns, startx, starty, hiders;

char grid[20][20];
char buffer[255];

bool valid(int x, int y){  
    if(x >= 0 && x < rows && y >= 0 && y < columns && grid[x][y] != 'X')  
        return true;  
    return false;  
}  

int main(){  
    scanf("%i%i%i", &rows, &columns, &hiders);  

    //this is where I set up the grid, at put it in the grid array.  

    for(int i = 0; i < rows; i++){  
        scanf("%s", &buffer);  
        for(int j = 0; j < columns; j++){  
            if(buffer[j] == 'G'){  
                startx = i;  
                starty = j;  
            }  
            grid[i][j] = buffer[j];  
        }  
    }  

    queue<ipair> Q; //keeps track of positions  
    queue<int> DQ; //keeps track of distance  
    int found = 0; //how many checkpoints are found  

    Q.push(make_pair(startx, starty)); //push start pos  
    DQ.push(0);  

    while(!Q.empty()){  
        int x = Q.front().first; //check x  
        int y = Q.front().second; //check y  

        if(found == hiders){ //if we found the amount needed  
            printf("%i", DQ.front()); // print current distance  
            return 0;  
        }  

        if(grid[x][y] == 'H'){ //found checkpoint  
            found++; //found a hider  
        }  
        //if it's possible to move right  
        if(valid(x + 1, y)){  
            Q.push(make_pair(x+1, y));  
            DQ.push(DQ.front() + 1);  
        }  
        //if it's possible to move left  
        if(valid(x - 1, y)){  
            Q.push(make_pair(x-1, y));  
            DQ.push(DQ.front() + 1);  
        }  
        //if it's possible to move up  
        if(valid(x, y + 1)){  
            Q.push(make_pair(x, y + 1));  
            DQ.push(DQ.front() + 1);  
        }  
        //if it's possible to move down  
        if(valid(x, y - 1)){  
            Q.push(make_pair(x, y - 1));  
            DQ.push(DQ.front() + 1);  
        }  

        Q.pop();  
        DQ.pop();  
        grid[x][y] = 'X'; //set the current coordinates as visited/walls  
    }  
}  

1 个答案:

答案 0 :(得分:0)

这不是BFS可以解决的问题。

乍一看Branch and Bound或Dynamic是要走的路。

B&B会肯定会让你到那里,但它很难实现,而且比动态慢。

首先出现的动态需要5个20x20的网格,但我并不是100%肯定它(它是第一次看到的反馈)。