广度优先搜索bfs与抓住那头奶牛(Catch that cow, poj3278)

广度优先搜索(Breadth First Search, BFS)是对树的逐层遍历,或者说,是对树的横向遍历。bfs是盲目的。

bfs常被用来求解达到某目标所需的 最少步骤数。例如poj3278,给定两个自然数n与k,每一步的移动有三种可能,n+1、n-1和n*2,问,从n出发,到达k所需要的最小移动次数。举个例子,n=5,k=17,则bfs步骤如下:


















两点 需要说明:
1.注意红色的叉,在搜索过程中可能产生已经搜索过的节点,这时要跳过。
2.已经搜索过第i层的节点,那么第i+1层的搜索从哪个节点开始?这时需要设置一个队列,i层已经搜索过的节点入队(在对第i-1层的节点分叉时),然后依次作为第i+1层节点的父节点出队。

下面是代码:
int step[MAX];    //访问到指定节点所需的步数
bool visited[MAX];    //指定节点是否已被访问
queue<int> bfstree;    //已访问的节点入队,用以引出要访问的下一层节点

memset(visited, false, sizeof(visited));    //初始时,所有节点都未被访问

int bfs()
{
    int head, next;

    visited[n] = 1;    //第一个节点被访问
    step[n] = 0;    //需要0步到达第一个节点
    bfstree.push(n);    //进队,用以引出下一层

    while (!bfstree.empty())
    {
        head = bfstree.front();
        bfstree.pop();

        //父节点有三个分支
        for (int i=0; i<3; ++i)
        {
            if (i==0) next=head-1;
            else if (i==1) next=head+1;
            else next = head*2;

            if (next<0||next>=MAX) continue;    //防止访问的节点越界

            if(!visited[next])    //已访问的节点需要被跳过
            {
                visited[next] = 1;
                step[next] = step[head] + 1;
                bfstree.push(next);
            }

            if (next == k) return step[next];
        }
    }

    return -1;
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值