Nightmare HDU1072

非常标准的BFS  

第一次写错了很多

1、到达4时设置为墙就好了  避免了死循环

2、不用开d数组   在结构体里面就行了

3、结构体初始化函数的写法: Node(int x=0,int y=0,int oil=0):x(x),y(y),oil(oil){}

4、bfs的FOR里面的判断条件可以写的很清晰!就判断可以的  不可以的直接不处理!

#include<bits/stdc++.h>
using namespace std;
int sx,sy,ex,ey;
int d[100][100],a[100][100],d2[100][100];
bool f[100][100];
int n,m;
struct aa
{
    int x;
    int y;
    int oil;
    aa(int x=0,int y=0,int oil=0):x(x),y(y),oil(oil){}
};




void bfs()
{


    const  int dr[4]={-1,0,1,0};
    const  int dc[4]={0,1,0,-1};

       queue<aa>q;
        memset(d,-1,sizeof(d));

        memset(f,true,sizeof(f));
        aa u(sx,sy,6);d[sx][sy]=0;
        q.push(u);
       // printf("u:%d %d %d
",u.x,u.y,u.oil);
        while(!q.empty())
        {

            aa u=q.front();q.pop();

            if(u.x==ex&&u.y==ey) {printf("%d
",d[ex][ey]);return;}
            for(int i=0;i<=3;i++)
            {
                aa v(u.x+dr[i],u.y+dc[i],u.oil-1);
                d[v.x][v.y]=d[u.x][u.y]+1;

                 if(v.x<1||v.x>n||v.y<1||v.y>m) continue ;
                if(v.oil==0)continue ;
                if(a[v.x][v.y]==4){   v.oil=6; a[v.x][v.y]=0;     q.push(v);      }
                if(a[v.x][v.y]!=0)
                {
                    //printf("v:%d %d %d
",v.x,v.y,v.oil);
                     q.push(v);}

            }



        }

        printf("-1
");
}



int main()
{
    int cas;cin>>cas;
    while(cas--)
        {


        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
              {
                scanf("%d",&a[i][j]);
                if(a[i][j]==2){sx=i;sy=j;}
                if(a[i][j]==3){ex=i;ey=j;}
              }
             bfs();

    }


    return 0;
}
View Code

第二次:简洁了许多

#include<bits/stdc++.h>
using namespace std;

int world[10][10];int sx,sy,ex,ey;int n,m;

struct node
{
    int x,y,d,oil;

    node(int x=0,int y=0,int d=0,int oil=0):x(x),y(y),d(d),oil(oil){}
};

void bfs()
{
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};

   node u(sx,sy,0,6);
    queue<node>q;
    q.push(u);

    while(!q.empty())
    {
        node u=q.front();q.pop();
        if(u.x==ex&&u.y==ey){printf("%d
",u.d);return;}

        for(int i=0;i<4;i++)
        {
            node v(u.x+dx[i],u.y+dy[i],u.d+1,u.oil-1);
            if(v.x>=1&&v.x<=n&&v.y>=1&&v.y<=m&&v.oil)
            {
                if(world[v.x][v.y]==4){v.oil=6;world[v.x][v.y]=0;q.push(v);}

                else if(world[v.x][v.y]>0) q.push(v);
            }
        }
    }
    printf("-1
");
}

int main()
{
   int cas;cin>>cas;
   while(cas--)
   {
      cin>>n>>m;
       for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
          {scanf("%d",&world[i][j]);
           if(world[i][j]==2){sx=i;sy=j;}
           if(world[i][j]==3){ex=i;ey=j;}

          }

       bfs();

   }

    return 0;
}
View Code

大神的简洁代码:

#include <iostream>
#include <algorithm>
#include <queue>
#include <memory.h>
#include <stdio.h>
using namespace std;
#define Size 8
/*
    这题目可以重复道路.只需要把控制炸弹的地方使用后,变成墙壁即可.
*/
struct Node
{
    int x;
    int y;
    int time;//time代表已用的时间.
    int rest;//rest代表剩余的时间.
    //按照时间从高到低排列.
    bool operator < (Node a) const
    {
        return this->time > a.time;
    }
};

int world[Size][Size];
int n, m;
int temp;
int dir[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
int sx, sy;
int rx, ry;
/*
    0代表墙壁.1代表正常路.2代表起点.3代表终点.4代表炸弹控制器.
*/
int bfs()
{
    priority_queue<Node> temp;
    Node now, next, s;
    s.x = sx;
    s.y = sy;
    s.time = 0;
    s.rest = 6;
    temp.push(s);

    while (!temp.empty())
    {
        now = temp.top();
        temp.pop();

        if (now.x == rx && now.y == ry && now.rest > 0)
        {
            return now.time;
        }
        //减枝.当剩余时间为1时.还没找到出口,说明到不了了.
        if (now.rest == 1)
            continue;

        for (int i = 0; i < 4; ++i)
        {
            next.x = now.x + dir[i][0];
            next.y = now.y + dir[i][1];
            next.time = now.time + 1;
            next.rest = now.rest - 1;
            //判断位置是否合理.
            if (next.x >= 0 && next.y >= 0 && next.x < n &&  next.y < m &&  world[next.x][next.y] != 0 && next.rest >= 1)
            {
                //如果他到了炸弹这里.
                if (world[next.x][next.y] == 4)
                {
                    next.rest = 6;
                    //改为墙壁即可.
                    world[next.x][next.y] = 0;
                }
                temp.push(next);
            }
        }
    }
    return -1;
}

int main()
{
    int t;
    scanf("%d", &t);
    for (int i = 0; i < t; ++i)
    {
        scanf("%d%d", &n,&m);
        memset(world, 0, sizeof(world));
        for (int j = 0; j < n; ++j)
        {
            for (int k = 0; k < m; ++k)
            {
                scanf("%d", &temp);
                //初始位置.
                if (temp == 2)
                {
                    sx = j;
                    sy = k;
                }
                //目标位置.
                else if (temp == 3)
                {
                    rx = j;
                    ry = k;
                }
                world[j][k] = temp;
            }
        }
        printf("%d
", bfs());
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/10298388.html