DFS BFS 入门......

DFS

​ 枚举所有可以到达目标状态的路径,递归或者借助栈来实现,对一个传入状态,遍历它的子状态,对每一个都进行判断,若合法,则递归搜索这一子状态,直到达成目标条件或者状态不合法,则回溯到父亲节点,搜索下一个子状态。


递归:

bool judge(参数列表){
    //参数不合法或越界时返回false 否则返回true
}
void dfs(传入状态){
    if(达成目标条件){
        输出信息或者修改信息;
        return;
    }
    for(遍历传入状态的所有子状态){
        if(judge(子状态)){
            传入状态加标记;
            dfs(子状态);
            传入状态取消标记//回溯
        }
    }
}

洛谷P1605 迷宫

int n,m,t,fx,fy,vis[10][10],arr[10][10],dict[4][2] = {{-1,0},{1,0},{0,-1},{0,1}},ans = 0;
bool judge(int i,int j){
    if(i < 1 || i > n || j < 1 || j > m) return false;//出边界 
    if(arr[i][j] || vis[i][j]) return false;//不合法 障碍 
    return true;
}
void dfs(int i,int j){
    if(i == fx && j == fy){
        ++ans;
        return;
    }
    for(int k=0;k<4;k++){
        int x,y;
        x = i+dict[k][0];
        y = j+dict[k][1];
        if(judge(x,y)){//判断下一个点是否合法 
            ++vis[i][j];//走过的地方加标记 
            dfs(x,y);//继续搜索下一个点 
            --vis[i][j];//回溯取消标记            
        }
    }
}

BFS

​ 较DFS高效,找到最快到达目标的一条路径,借助队列实现,状态A的子状态均入队。队列不为空时,弹出队首元素,进行搜索-->队列空;

void judge(node){
    if(非法条件为真 || 范围越界) return false;
    return true;
}
void bfs(A){
    queue<node> q;
    q.push(A);
    while(!q.empty()){
        temp = q.front();
        q.pop();
        if(temp 达成目标条件){
            输出信息;
        }
        if(judge(temp)){//子状态合法则入队
            q.push(temp);
            ++vis[temp];//每个节点只访问一次
        }
    }
}

洛谷 P1443 马的遍历

int n,m,sx,sy,map[410][410],dir[2][4] = {{-2,-1,1,2},{-2,-1,1,2}};
bool vis[410][410];
memset(vis,false,sizeof(vis));
memset(map,0xff,sizeof(map));//初始化为-1
struct point{
    int x;
    int y;
}node,top;
//马走日字... 坐标 1 2 或 2 1 变换 
bool judge(int i,int j){
    if(i < 0 || i >= n || j < 0 || j >= m) return false;
    if(vis[i][j]) return false;
    return true;
}
void bfs(int x,int y){
    vis[x][y] = 1;
    map[x][y] = 0;//到初始点需要0步
    queue<point> t;
    node.x = x;
    node.y = y;
    t.push(node);
    while(!t.empty()){
        top = t.front();
        t.pop();
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                if(abs(dir[0][i]) != abs(dir[1][j])){//排除不合法的移动 
                    int _x = top.x + dir[0][i];
                    int _y = top.y + dir[1][j];
                    if(judge(_x,_y)){//判断这一步是否合法 
                        node.x = _x;
                        node.y = _y;
                        t.push(node);
                        vis[_x][_y] = 1;//标记 第一次到达该点的步数一定最优 
                        map[_x][_y] = map[top.x][top.y] + 1;//路径+1                      
                    }
                }
            }
        } 
    } 
}

猜你喜欢

转载自www.cnblogs.com/honey-cat/p/11831077.html