2017/8/2训练日记(关于bfs菜鸟入门)

本文介绍了广度优先搜索(BFS)的基本概念及其在解决特定类型问题中的应用。包括使用BFS寻找从初始状态到目标状态的最短路径,提供了详细的代码示例,并对比了不同实现方式的特点。

今天一天都是在a搜索的题目,但感觉效率不高,并没有a出多少道题来QAQ

先补充个知识点,做题的时候用到了:

string &assign(const string &s,int start,int n);把字符串s中从start开始的n个字符赋给当前字符串;

assign() 函数将区间[start, end)的元素赋到当前vector,或者赋num个值为val的元素到vector中。

不过这个函数将会清除掉为vector赋值以前的内容。

再有就是有关字母的题存储的话可以相应的转化成数字可能会比较好存一些,c[zimu[i]-'A'+1]++类似于这种形式比较好操作。

接下来进入正题:广搜

其实今天做的几个属于广搜的题目,本来广搜的题就不擅长,从这里先把比较基础的好好总结一下:(感觉自己好菜啊,菜哭)

广度优先搜索就是一种全局的遍历操作,

遍历的方法就是这样:选择图中任意一个顶点 vv 作为起点进行访问,并将顶点 vv 标为已访问。

遍历并访问与顶点 vv 相邻且未被访问的所有顶点 ,接着遍历并访问与顶点相邻且未被访问的顶点

,也就是依次访问所有相邻顶点的相邻顶点。以此类推,直到所有顶点均被访问。

形象一点的话就像:你眼镜掉到地上了,你蹲下去找肯定是先找离你最近的地方,再往扩一点……

再不形象的话直接上代码比较好解释

/** 
 * 广度优先搜索比较核心的代码

bool  visit[10000001];//用来表示节点是否访问过
bool BFS(Node& Vs, Node& Vd)//Vs是起点,Vd是终点

{  
    queue<Node> Q;  
    Node Vn, Vw;  
    int i;  
  
    //初始状态将起点放进队列Q  
    Q.push(Vs);  
     visit[Vw] = true;//设置节点已经访问过了!  
  
    while (!Q.empty()){//队列不为空,继续搜索!  
        //取出队列的头Vn  
        Vn = Q.front();  
  
        //从队列中移除  
        Q.pop();  
  
        while(Vw = Vn通过某规则能够到达的节点){  
            if (Vw == Vd){//找到终点了!  
                //把路径记录,这里没给出解法  
                return true;//返回  
            }  
  
            if (isValid(Vw) && !visit[Vw]){  
                //Vw是一个合法的节点并且为白色节点  
                Q.push(Vw);//加入队列Q  
                visit[Vw] = true;//设置节点颜色  
            }  
        }  
    }  
    return false;//无解  
}  

********************************************************************************************

或:

const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量
struct State // BFS 队列中的状态数据结构
{
int x,y; // 坐标位置
int Step_Counter; // 搜索步数统计器
};


State a[maxn];

bool CheckState(State s) // 约束条件检验
{
if(!vst[s.x][s.y] && ...) // 满足条件
return 1;
else // 约束条件冲突
return 0;
}


void bfs(State st)
{
queue <State> q; // BFS 队列
State now,next; // 定义2 个状态,当前和下一个
st.Step_Counter=0; // 计数器清零
q.push(st); // 入队
vst[st.x][st.y]=1; // 访问标记
while(!q.empty())
{
now=q.front(); // 取队首元素进行扩展

q.pop(); // 队首元素出队

if(now==G) // 出现目标态,此时为Step_Counter 的最小值,可以退出即可
{
...... // 做相关处理
return;
}
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
next.y=now.y+dir[i][1];
next.Step_Counter=now.Step_Counter+1; // 计数器加1
if(CheckState(next)) // 如果状态满足约束条件则入队
{
q.push(next);
vst[next.x][next.y]=1; //访问标记
}
}
}
 return;
}


int main()
{
......
 return 0;
}

上面给出了两套模拟代码但都没有实际意义只是用来表述下广搜的代码过程

BFS适合此类题目:给定初始状态跟目标状态,要求从初始状态到目标状态的最短路径。

但是直到今天为止,我目前出现的问题是可以看出问题的做法,但是并不能写出ac代码,甚至有的题连基本的bfs代码都写不出来QAQ

所以今天晚上我一直在翻阅大佬们关于bfs的博客,还是感叹下自己看的题少,菜哭QAQ

https://wenku.baidu.com/view/da6d5997ff00bed5b8f31d46.html


另附带一个dfs的博客

https://wenku.baidu.com/view/994fcc3d69dc5022abea0047.html?re=view

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值