算法笔记 --第八章 提高篇(2) --搜索专题

这里写图片描述

读书笔记

前言

这里写图片描述
当时学DFS和BFS做到一点笔记.再记录一次
(1)DFS一般不能保证找到最优解
(2)BFS:如果问题有解,一定能找到最优解
下面开始读书笔记

DFS

这里写图片描述
第一次学DFS的时候是学习怎么走迷宫,但是书上给了另一种看法:迷宫是图(数据结构),可以转换为树(应该是最小生成树)。如果用走迷宫的想法,即是当你遇到分岔口时,你可以选择的分支走(就像树的父亲节点和儿子节点的分支)。而遇到死路,就像到了叶子节点.
这里写图片描述
当然重点并不在这,书上介绍了背包问题,介绍了用DFS的眼光去看这个问题:
对于每一个物品,有两种选择,选或者不选,这就像遇到了分岔口。当所有物体都处理完毕后,就是到了叶子节点.
这里写图片描述
因为有背包容量这个限制条件,所以每次选择一个新物体的时候,如果选择的物体总重超过了背包容量,就不应该进入选择物体的分岔口了。,这就是剪枝
这里写图片描述



BFS

书中给了一个模板:

void BFS(int s){
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        取出队首元素TOP;
        访问队首元素TOP;
        将队首元素出队;
        将top下一层节点中未曾入队的节点全部入队.
    }
}

书上给了一个例题,现在也写入读书笔记吧
给出一个 M N 的矩阵,矩阵中的元素为0或1.称位置(x,y)与其上下左右四个位置(x,y+1),(x,y-1),(x+1,y),(x-1,y)是相邻的。如果矩阵中有若干个1是相邻的,那么称这些1构成了一个,求给定矩阵中的个数

                            0 1 1 1 0 0 1
                            0 0 1 0 0 0 0
                            0 0 0 0 1 0 0
                            0 0 0 1 1 1 0 
                            1 1 1 0 1 0 0
                            1 1 1 1 0 0 0

这个问题求解的基本思路是:枚举每一个元素,如果是0,跳过,如果是1,则使用BFS查询与该位置相邻的4个位置,判断它们是否为。而防止走回头路,一般可以设置一个bool型数组inq来记录每一个已经走过的路。
little trick:可以使用两个增量数组来表示4个方向

int X[] ={0,0,1,-1};     //下,上,右,左
int Y[] ={1,-1,0,0};
for(int i=0;i<4;i++){
    newX = nowX+X[i];
    newY = nowY+Y[i];
}

code

//matrix 是输入的矩阵
struct node{
    int  x,y;
}Node;
bool inq[M][N]={false};
int X[] ={0,0,1,-1};     //下,上,右,左
int Y[] ={1,-1,0,0};

bool judge(int x,int y){
    if(x>=n ||x<0 || y>=m || y<0)    return false;
    if(matrix[x][y] ==0 || inq[x][y] ==true)    return false;
    return true;
}
void BFS(int x,int y){
    queue<int> q;
    Node.x=x,Node.y=y;
    q.push(Node);
    inq[x][y] =true;
    while(!q.empty()){
        node top = q.top();
        q.pop();
        for(int i=0;i<4;i++){
            int newX =top.x+X[i];
            int newY =top.y+Y[i];
            if(judge(newX,newY)){
                Node.x = newX;
                Node.y = newY;
                q.push(Node);
                inq[newX][newY]=true;
            }
        }
    }
}
int main()
{
    //do input 
    int count=0;
    for(int x=0;x<M;x++)
        for(int y=0;y<N;y++)
            if(matrix[x][y] ==1 && inq[x][y]==false){
                count++;
                BFS(x,y);
            }
}

完结撒花d=====( ̄▽ ̄*)b

这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41256413/article/details/81738137