UVA439-最短路-BFS

前一段时间学BFS(宽度优先搜索)最短路的时候,紫书上那个题感觉太复杂了,debug了几天。。。还好最后AC了。

今天发现一个简单的题,而且还觉得挺有意思的,用这个题来学BFS最短路我觉得更合适。这道题题意简单,输入输出也简单,所以代码较短。

题目链接:https://vjudge.net/problem/UVA-439

题目内容:

 

 

 

分析:

 第一次看到用bfs求最短路的代码感觉很神奇,竟然还可以这样做。在没有学bfs之前,我都是用dfs遍历所有路找出最短的(超时难免了)。bfs可以用队列实现,要做的就是把当前所在节点的所有下一个节点入列,这样就保证了从队列读取出来的节点都是第n步或者n+1步了,直到发现终点为止,这条路就是最短路。

实现这个思路有几个巧妙的地方,就是该怎么找第n+1个节点。在这道题中,下一个节点可能有8个,用循环可以构造出这8个节点出来(详情见代码)。当然8个节点并不是都可以,超出棋盘的去掉,已经入过列的节点去掉。

还有个问题就是怎么算走了多少步。我把这个数据存在一个8*8数组中,每个节点一定有唯一的步数,并且还顺便把这个数组用来判断一个节点是否走过。

实现代码: 

其中的vis数组很关键,构造下一个节点代码部分较巧妙。

#include<cstdio>
#include<queue>
#include<cstring>
#include<cstdlib>
struct Point
{
    Point(int r,int c):r(r),c(c) {}
    int r,c;
};

char s1[3],s2[3];
int vis[8][8],begin_r,begin_c,end_r,end_c;

int bfs()
{
    memset(vis,0,sizeof(vis));
    vis[begin_r][begin_c]=1;
    std::queue<Point> q;
    Point p(begin_r,begin_c);
    q.push(p);

    while(!q.empty())
    {
        p=q.front();
        q.pop();
        if(p.r==end_r&&p.c==end_c)
            break;
        for(int i=-2; i<3; ++i)
            for(int j=-2; j<3; ++j)
                if(i&&j&&abs(i)!=abs(j)&&p.r+i>-1&&p.r+i<8&&
                   p.c+j>-1&&p.c+j<8&&!vis[p.r+i][p.c+j])
                   {
                        vis[p.r+i][p.c+j]=vis[p.r][p.c]+1;
                        q.push(Point(p.r+i,p.c+j));
                   }
    }
    return vis[p.r][p.c]-1;
}
int main()
{
    while(scanf("%s",s1)==1)
    {
        begin_r=s1[0]-'a';
        begin_c=s1[1]-'1';
        scanf("%s",s2);
        end_r=s2[0]-'a';
        end_c=s2[1]-'1';
        printf("To get from %s to %s takes %d knight moves.\n",s1,s2,bfs());
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值