POJ 3170(bfs求最短路)

Bessie要在网格地图中找到并带回一株灌木给守卫森林的骑士们。面对不可通行区域和复杂的地形,她如何用最少的时间完成任务?本篇介绍了一个寻找最优路径的算法问题。
Knights of Ni
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 2070 Accepted: 890

Description

Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded by the Knights of Ni. In order to pass through safely, the Knights have demanded that she bring them a single shrubbery. Time is of the essence, and Bessie must find and bring them a shrubbery as quickly as possible. 

Bessie has a map of of the forest, which is partitioned into a square grid arrayed in the usual manner, with axes parallel to the X and Y axes. The map is W x H units in size (1 <= W <= 1000; 1 <= H <= 1000). 

The map shows where Bessie starts her quest, the single square where the Knights of Ni are, and the locations of all the shrubberies of the land. It also shows which areas of the map can be traverse (some grid blocks are impassable because of swamps, cliffs, and killer rabbits). Bessie can not pass through the Knights of Ni square without a shrubbery. 

In order to make sure that she follows the map correctly, Bessie can only move in four directions: North, East, South, or West (i.e., NOT diagonally). She requires one day to complete a traversal from one grid block to a neighboring grid block. 

It is guaranteed that Bessie will be able to obtain a shrubbery and then deliver it to the Knights of Ni. Determine the quickest way for her to do so.

Input

Line 1: Two space-separated integers: W and H. 

Lines 2..?: These lines describe the map, row by row. The first line describes the most northwest part of the map; the last line describes the most southeast part of the map. Successive integers in the input describe columns of the map from west to east. Each new row of a map's description starts on a new input line, and each input line contains no more than 40 space-separated integers. If W <= 40, then each input line describes a complete row of the map. If W > 40, then more than one line is used to describe a single row, 40 integers on each line except potentially the last one. No input line ever describes elements of more than one row. 

The integers that describe the map come from this set: 
0: Square through which Bessie can travel 
1: Impassable square that Bessie cannot traverse 
2: Bessie's starting location 
3: Location of the Knights of Ni 
4: Location of a shrubbery

Output

Line 1: D, the minimum number of days it will take Bessie to reach a shrubbery and bring it to the Knights of Ni.

Sample Input

8 4
4 1 0 0 0 0 1 0
0 0 0 1 0 1 0 0
0 2 1 1 3 0 4 0
0 0 0 4 1 1 1 0

Sample Output

11

Hint

Explanation of the sample: 

Width=8, height=4. Bessie starts on the third row, only a few squares away from the Knights. 

Bessie can move in this pattern to get a shrubbery for the Knights: N, W, N, S, E, E, N, E, E, S, S. She gets the shrubbery in the northwest corner and then makes her away around the barriers to the east and then south to the Knights.

Source

两次bfs,分别求出2到4的距离和3到4的距离,求两个距离相加的最小值。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 1e3 + 10;
#define INF 0x3f3f3f3f
int n, m;
int a[maxn][maxn];
int vis[maxn][maxn];
int d1[maxn][maxn];
int d2[maxn][maxn];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
vector<pair<int, int> > b;
void bfs(int x, int y, int tt[][maxn]){
    queue<pair<int, int> > q;
    memset(vis, 0, sizeof vis);
    q.push(make_pair(x, y));
    int cnt = 0;
    while(!q.empty()){
        pair<int, int> t = q.front(); q.pop();
        if(a[t.first][t.second] == 4) cnt++;
        if(cnt == b.size()) return;
        for(int i = 0; i < 4; i++){
            int xx = t.first + dx[i];
            int yy = t.second + dy[i];
            if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
            if(a[xx][yy] != 1 && !vis[xx][yy]){
                vis[xx][yy] = 1;
                tt[xx][yy] = tt[t.first][t.second] + 1;
                q.push(make_pair(xx, yy));
            }
        }
    }
}
int main(){
    int t1, t2, p1, p2;
    scanf("%d%d", &m, &n);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++){
            scanf("%d", &a[i][j]);
            if(a[i][j] == 3){
                t1 = i;
                t2 = j;
            }
            if(a[i][j] == 2){
                p1 = i;
                p2 = j;
            }
            if(a[i][j] == 4){
                b.push_back(make_pair(i, j));
            }
        }
    int minn = INF;
    memset(d1, 0, sizeof d1);
    memset(d2, 0, sizeof d2);
    bfs(p1, p2, d1);
    bfs(t1, t2, d2);
    for(int i = 0; i < b.size(); i++){
        int ss = b[i].first, pp = b[i].second;
        if(d1[ss][pp] && d2[ss][pp])
        minn = min(minn, d1[ss][pp] + d2[ss][pp]);
    }
    printf("%d\n", minn);
}


当前提供的引用内容并未提及关于POJ平台上编号为3487的问题描述或解决方案。然而,可以通过分析已知的其他POJ题目来推测解决此类问题的一般方法。 通常情况下,在处理编程竞赛中的图论、搜索算法或其他类型的计算问题时,需要明确以下几个方面: 1. **输入数据结构**:了解输入的数据形式以及如何解析这些数据。 2. **核心算法设计**:确定解决问题的核心算法(如广度优先搜索[BFS]、深度优先搜索[DFS]、动态规划等)。 3. **边界条件与优化策略**:识别可能存在的特殊测试用例并采取相应的优化措施。 尽管未提供具体针对POJ 3487的信息,但可以借鉴类似的BFS应用实例[^1] 或者皇后放置问题中的回溯法实现逻辑[^2] 来构建解题框架。如果该问题是基于路径寻找或者状态转移,则很可能涉及队列操作配合邻接表表示连通关系;如果是组合排列类挑战则需注意剪枝技巧减少不必要的递归调用次数。 以下是假设此题属于短路经范畴的一个基础伪代码模板作为参考: ```python from collections import deque def bfs(start_node, target_node): visited = set() queue = deque([(start_node, 0)]) # (current node, steps) while queue: current, step_count = queue.popleft() if current == target_node: return step_count for neighbor in get_neighbors(current): # function defining adjacency list logic if neighbor not in visited: visited.add(neighbor) queue.append((neighbor, step_count + 1)) return -1 # no path found between start and target nodes. ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值