zoukankan      html  css  js  c++  java
  • 题解 【洛谷P1332】血色先锋队

    题面:https://www.luogu.org/problemnew/show/P1332

    很容易看出,这是一个典型的广度优先搜索,也就是众多OIer口中的bfs。

    先给各位普及一下bfs(部分来自百度):

    广度优先搜索(Breadth-First Search),又称作宽度优先搜索,或横向优先搜索,简称bfs,是一种基础算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点,如果发现目标,则演算终止。广度优先搜索的实现一般采用队列。

    其实,广度优先搜索是搜索算法的基础,想要成为一名优秀的OIer,广度优先搜索和深度优先搜索都是必须掌握的!

    此题告诉了我们有A个感染源,B个领主,我们可以定义一个vis数组,若当前坐标的vis值为1,那么此处就没有被感染;否则,当前坐标就已被感染。

    我们可以首先用bfs算出每个坐标被感染的时间,最后直接输出领主被感染的时间即可。

    话不多说,上代码:

    #include<bits/stdc++.h>//万能头文件
    using namespace std;//开启标准名字空间
    struct Node
    {
        int x,y,Time;//x为横坐标,y为纵坐标,Time为被感染时间
    } s[250010];//设置结构体数组维护队列
    int head,tail;//分别为头指针、尾指针
    int n,m,a,b,vis[505][505],c[250010],d[250010],e,f,i,j,
        k;//vis的意义同分析,c数组和d数组为感染源坐标,e、f为领主坐标
    int P[510][510];//每个坐标被感染时间
    void bfs()  //开始bfs
    {
        tail=0;
        head=0;//初始化指针
        for(i=1; i<=a; i++)  //先把已知条件加入队列,并初始化时间
        {
            s[++tail].x=c[i];//相当于tail++,s[tail].x=c[i]
            s[tail].y=d[i];
            s[tail].Time=0;
            P[c[i]][d[i]]=0;
        }
        while(head<tail)  //如果队列中还有元素
        {
            head++;//头指针加1
            int h=s[head].x,r=s[head].y,tmp=s[head].Time;//取出队首元素
            if(h+1<=n && vis[h+1][r]==0)  //往右扩展,若合法加入队列
            {
                s[++tail].x=h+1;//更新x坐标
                s[tail].y=r;//更新y坐标
                P[h+1][r]=s[tail].Time=tmp+1;//更新时间
                vis[h+1][r]=1;//记录为已被感染
            }
            //以下每步操作意义同上
            if(h-1>=1 && vis[h-1][r]==0)  //往左扩展,若合法加入队列
            {
                s[++tail].x=h-1;
                s[tail].y=r;
                P[h-1][r]=s[tail].Time=tmp+1;
                vis[h-1][r]=1;
            }
            if(r+1<=m && vis[h][r+1]==0)  //往上扩展,若合法加入队列
            {
                s[++tail].x=h;
                s[tail].y=r+1;
                P[h][r+1]=s[tail].Time=tmp+1;
                vis[h][r+1]=1;
            }
            if(r-1>=1 && vis[h][r-1]==0)  //往下扩展,若合法加入队列
            {
                s[++tail].x=h;
                s[tail].y=r-1;
                P[h][r-1]=s[tail].Time=tmp+1;
                vis[h][r-1]=1;
            }
        }
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&a,&b);//输入矩阵大小、感染源个数和领主个数
        for(i=1; i<=a; i++)
        {
            scanf("%d%d",&c[i],&d[i]);//输入感染源坐标
            vis[c[i]][d[i]]=1;//记录为已被感染
        }
        bfs();//遍历每个坐标被感染的时间
        for(i=1; i<=b; i++)
        {
            scanf("%d%d",&e,&f);//输入领主坐标
            printf("%d\n",P[e][f]);//直接输出被感染时间
        }
        return 0;//结束
    }

    有些人直接枚举每一个领主和感染源,求他们曼哈顿距离,但在矩阵过大时会TLE,所以bfs总是比暴力好的。

  • 相关阅读:
    Using AlloyTouch to control three.js 3D model
    AlloyTouch与three.js 3D模型交互
    移动Web触摸与运动解决方案AlloyTouch开源啦
    transformjs玩转星球
    swing with transformjs
    和transformjs一起摇摆
    getting started with transformjs
    移动Web利器transformjs入门
    腾讯AlloyTeam移动Web裁剪组件AlloyCrop正式开源
    Why AlloyFinger is so much smaller than hammerjs?
  • 原文地址:https://www.cnblogs.com/xsl19/p/10414735.html
Copyright © 2011-2022 走看看