Skip to content

BFS

平面坐标系中模拟向周围 BFS。

C++
const int DIR[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 四个方向
const int DIR[][2] = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}}; // 八个方向

void bfs(int x, int y) {
    queue<PII> que;
    // ...
    while (!que.empty()) {
        auto pr = que.front();
        que.pop();
        int x = pr.first, y = pr.second;
        // ...
        for (auto& DIR : DIRS) {
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && /* 其它条件 */) {
            	que.push({nx, ny});
                // ...
            }
        }
    }
}
const int DIR[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 四个方向
const int DIR[][2] = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}}; // 八个方向

void bfs(int x, int y) {
    queue<PII> que;
    // ...
    while (!que.empty()) {
        auto pr = que.front();
        que.pop();
        int x = pr.first, y = pr.second;
        // ...
        for (auto& DIR : DIRS) {
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && /* 其它条件 */) {
            	que.push({nx, ny});
                // ...
            }
        }
    }
}

求「最少能从初始状态到达结束状态的步数」问题。

Java
import java.util.*;
import java.io.*;

public class Main {
    // 状态对象
    static class State {
        T content; // 状态
        int step; // 步数

        State(T content, int step) {
            // 初始化
            this.content = content;
            this.step = step;
        }

        // 重写equals方法对比状态是否相同
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof State)) return false;
            State s = (State) obj;
            // 对比状态
            // ...
        }

        // 重写hashCode方法用于存入集合 以便于快速确认状态的存在与否
        @Override
        public int hashCode() {
            // ...
        }

        // 由当前状态生成新的状态
        State newFrom(T content) {
            // ...
            return new State(content, step + 1);
        }
    }

    static State origin, target;
    
    public static void main(String[] args) throws IOException {
        // 输入状态 初始状态的步数皆为 0
        origin = new State(/* 初始状态 */, 0);
        target = new State(/* 目标状态 */, 0);
        // 输出结果(最少能从初始状态到达结束状态的步数)
        System.out.println(bfs());
    }

    static int bfs() {
        Queue<State> que = new LinkedList<>(); // BFS辅助队列
    	Set<State> vis = new HashSet<>(); // 判断状态是否已经见到过 用于剪枝
        que.offer(origin); // 放入初始状态
        while (!que.isEmpty()) {
            // 取出队尾状态
            State state = que.poll();
            // base case: 当前状态和达到目标则直接返回步数即是最短步数
            if (state.equals(target)) return state.step;
            // 枚举所有合法的状态转移
            for (eachValid in possibilities) {
                // 生成新状态
                State newState = state.newFrom(eachValid);
                // 若新生成的状态在以前没遇到过就把它加入队列与集合
                if (!set.contains(newState)) {
                    set.add(newState);
                    que.add(newState);
                }
            }
        }
        return -1;
    }
}
import java.util.*;
import java.io.*;

public class Main {
    // 状态对象
    static class State {
        T content; // 状态
        int step; // 步数

        State(T content, int step) {
            // 初始化
            this.content = content;
            this.step = step;
        }

        // 重写equals方法对比状态是否相同
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof State)) return false;
            State s = (State) obj;
            // 对比状态
            // ...
        }

        // 重写hashCode方法用于存入集合 以便于快速确认状态的存在与否
        @Override
        public int hashCode() {
            // ...
        }

        // 由当前状态生成新的状态
        State newFrom(T content) {
            // ...
            return new State(content, step + 1);
        }
    }

    static State origin, target;
    
    public static void main(String[] args) throws IOException {
        // 输入状态 初始状态的步数皆为 0
        origin = new State(/* 初始状态 */, 0);
        target = new State(/* 目标状态 */, 0);
        // 输出结果(最少能从初始状态到达结束状态的步数)
        System.out.println(bfs());
    }

    static int bfs() {
        Queue<State> que = new LinkedList<>(); // BFS辅助队列
    	Set<State> vis = new HashSet<>(); // 判断状态是否已经见到过 用于剪枝
        que.offer(origin); // 放入初始状态
        while (!que.isEmpty()) {
            // 取出队尾状态
            State state = que.poll();
            // base case: 当前状态和达到目标则直接返回步数即是最短步数
            if (state.equals(target)) return state.step;
            // 枚举所有合法的状态转移
            for (eachValid in possibilities) {
                // 生成新状态
                State newState = state.newFrom(eachValid);
                // 若新生成的状态在以前没遇到过就把它加入队列与集合
                if (!set.contains(newState)) {
                    set.add(newState);
                    que.add(newState);
                }
            }
        }
        return -1;
    }
}