zoukankan      html  css  js  c++  java
  • hdu 1044 BFS(压缩图)+DFS

    题意:

                 给你起点,终点,图上有墙有路还有宝物,问你在规定时间内能否能到终点,如果能问最多能捡到多少宝物.


    思路:

              看完这个题目果断 BFS+三维的mark[][][] 第三维用二进制压缩的思想去解决,结果TLE了,我后来在网上看了看,发现有人用二进制压缩ac了,这更坚定了我的决心啊,不停的优化 超时 优化 超时 就这样我超时了 50多次,我tm恶心了,直接粘了个网上说和我想法一样的代码交上去了,结果 TLE 了, 我 fuck ,超时了早说啊...闭嘴 ,可能是数据加强了.

    下面说一下正解 ,观察我们发现,题目中给的宝贝数量并不多,最多才10 ,其实我们可以先 BFS求出所有点的最短路,这些点包括 ,起点,终点,宝物,求完最短路我们其实就把这个图压缩成了最多 10 + 1 + 1 个点,压缩了图之后就是暴力DFS了,12个点压力也有点大,所以要剪枝 , 在深搜的时候如果发现当前的可满足ans 已经等于宝物总和了,那么不用在搜了,直接return 到最外面,或者可以再加上一个就是,当前的所用时间 + 当前到终点的时间 大于题目给的时间限制了,直接return 到上一层; 



    /*
    先BFS把图压缩,在DFS爆搜
    */


    #include<stdio.h>
    #include<string.h>
    #include<queue>


    #define N1 60
    #define N2 15 


    using namespace std;


    typedef struct
    {
       int x ,y ,t;
    }NODE;


    NODE xin ,tou;
    int mark_bfs[N1][N1] ,mark_dfs[N2];
    int dis[N2][N2] ,money[N2];
    int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
    char map[N1][N1];
    int xx ,yy ,tt ,mm ,ss ,nn;


    bool ok(int x ,int y)
    {
       if(x >= 0 && x < xx && y >= 0 && y < yy && map[x][y] != '*' && !mark_bfs[x][y])
       return 1;
       return 0;
    }


    void BFS(int x ,int y ,int key)// 求那几个点之间的最短路,key当前是起始点.
    {
       memset(mark_bfs ,0 ,sizeof(mark_bfs));
       mark_bfs[x][y] = 1;
       xin.x = x ,xin.y = y ,xin.t = 0;
       queue<NODE>q;
       q.push(xin);
       while(!q.empty())
       {
          tou = q.front();
          q.pop();
          for(int i = 0 ;i < 4 ;i ++)
          {
             xin.x = tou.x + dir[i][0];
             xin.y = tou.y + dir[i][1];
             xin.t = tou.t + 1;
             if(ok(xin.x ,xin.y))
             {
                mark_bfs[xin.x][xin.y] = 1;
                q.push(xin);
                if(map[xin.x][xin.y] == '@')
                dis[key][0] = xin.t;
                if(map[xin.x][xin.y] == '<')
                dis[key][nn+1] = xin.t;
                if(map[xin.x][xin.y] >= 'A' && map[xin.x][xin.y] <= 'J')
                dis[key][map[xin.x][xin.y] - 64] = xin.t;
             }
          }
       }
       return ;
    }


    void DFS(int s ,int time ,int mon) // s是当前点 ,time是当前所用时间,mon是当前财

    //富值
    {
       if(time > tt || mm == ss) return;
       if(s == nn + 1 && mm < mon)
       mm = mon;
       for(int k = 1 ;k <= nn + 1 ;k ++)
       {
          if(!dis[s][k] || mark_dfs[k]) continue;
          mark_dfs[k] = 1;
          DFS(k ,time + dis[s][k] ,mon + money[k]);
          mark_dfs[k] = 0;
       }
    }


    int main ()
    {
       int i ,j ,t ,cas = 1;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d %d %d %d" ,&yy ,&xx ,&tt ,&nn);
          money[0] = money[nn+1] = 0;
          for(ss = 0 ,i = 1 ;i <= nn ;i ++)
          {
             scanf("%d" ,&money[i]);
             ss += money[i];
          }
          for(i = 0 ;i < xx ;i ++)
          scanf("%s" ,map[i]);
          memset(dis ,0 ,sizeof(dis));
          for(i = 0 ;i < xx ;i ++)
          for(j = 0 ;j < yy ;j ++)
          {

             // 起点是 0 ,终点是 n + 1 ,宝物是 1 ---- n其他的墙和路都不要了,深搜时没有用
             if(map[i][j] == '*')
             continue;
             if(map[i][j] == '@')
             BFS(i ,j ,0);
             if(map[i][j] == '<')
             BFS(i ,j ,nn + 1);
             if(map[i][j] >= 'A' && map[i][j] <= 'J')
             BFS(i ,j ,map[i][j] - 64);
          }
          mm = -1;
          memset(mark_dfs ,0 ,sizeof(mark_dfs));
          mark_dfs[0] = 1;
          DFS(0 ,0 ,0);
          printf("Case %d: " ,cas ++);
          if(mm == -1)
          printf("Impossible ");
          else
          printf("The best score is %d. " ,mm);
          if(t) printf(" ");
       }
       return 0;
    }
       
          
          


  • 相关阅读:
    Linux下MySQL数据库常用基本操作 一
    Cdnbes负载均衡的权重用法解释
    docker安装
    centos网卡配置和防火墙停止和启动
    Excel 如何锁定表头
    权值线段树 基础入门知识详解
    JZOJ 3362. 【NOI2013模拟】数数(DFS)
    JZOJ 3348. 【NOI2013模拟】秘密任务(最短路+最小割唯一性)
    JZOJ 3303. 【集训队互测2013】城市规划(卷积+分治NTT)
    FFT快速傅里叶变换(超详细的入门学习总结)
  • 原文地址:https://www.cnblogs.com/csnd/p/12063308.html
Copyright © 2011-2022 走看看