zoukankan      html  css  js  c++  java
  • hdu 4771 bfs 从起点经过几个特定的点所需的最短时间

    【题意】:给你一个n*m的地图,问你从起点出发,必须经过几个特定的点所需的最短时间

    【思路】:地图较小且这里最多有4个点必须经过的点,所以直接BFS就可以了,step[x][y][zt]  表示在点[x,y]且已经走过的点的状态为zt(二进制表示)(要是数据量大一点 可以先预处理这些必须经过的点两两之间的最短距离再状态压缩dp)(直接看记录盼盼的代码算了)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<cstring>
      5 using namespace std;
      6 struct node
      7 {
      8     int x,y;
      9     int zt,step;
     10 };
     11 bool vist[105][105][(1<<4)];
     12 int n,m,k,fx[4][2]={1,0,-1,0,0,1,0,-1},tol,qx,qy;
     13 char s[105][105];
     14 void bfs(int zt)
     15 {
     16     node p;
     17     p.x=qx;
     18     p.y=qy;
     19     p.step=0;
     20     p.zt=zt;
     21     memset(vist,false,sizeof(vist));
     22     vist[p.x][p.y][p.zt]=true;
     23     queue<node>q;
     24     q.push(p);
     25     while(!q.empty())
     26     {
     27         p=q.front();
     28         q.pop();
     29         if(p.zt==(1<<k)-1)
     30         {
     31             printf("%d
    ",p.step);
     32             return;
     33         }
     34         for(int i=0;i<4;i++)
     35         {
     36             node p1;
     37             p1.x=p.x+fx[i][0];
     38             p1.y=p.y+fx[i][1];
     39             p1.step=p.step+1;
     40             p1.zt=p.zt;
     41             if(p1.x>=0&&p1.x<n&&p1.y>=0&&p1.y<m&&s[p1.x][p1.y]!='#')
     42             {
     43                 if(s[p1.x][p1.y]>=1&&s[p1.x][p1.y]<=k)
     44                 {
     45                     int tmp=(1<<(s[p1.x][p1.y]-1));
     46                     p1.zt|=tmp;
     47                     if(!vist[p1.x][p1.y][p1.zt])
     48                     {
     49                         vist[p1.x][p1.y][p1.zt]=true;
     50                         q.push(p1);
     51                     }
     52                 }
     53                 else
     54                 {
     55                     if(!vist[p1.x][p1.y][p1.zt])
     56                     {
     57                         vist[p1.x][p1.y][p1.zt]=true;
     58                         q.push(p1);
     59                     }
     60                 }
     61             }
     62         }
     63     }
     64     printf("-1
    ");
     65 }
     66 int main()
     67 {
     68     while(scanf("%d%d",&n,&m)>0)
     69     {
     70         if(n==0&&m==0) break;
     71         tol=1;
     72         for(int i=0;i<n;i++)
     73         {
     74             scanf("%s",s[i]);
     75             for(int j=0;j<m;j++)
     76             {
     77                 if(s[i][j]=='@')
     78                 {
     79                     s[i][j]='.';
     80                     qx=i;
     81                     qy=j;
     82                 }
     83             }
     84         }
     85         scanf("%d",&k);
     86         int zt=0;
     87         for(int i=0;i<k;i++)
     88         {
     89             int x,y;
     90             scanf("%d%d",&x,&y);
     91             x--;
     92             y--;
     93             s[x][y]=tol++;
     94             if(x==qx&&y==qy)
     95             {
     96                 zt|=(1<<(s[x][y]-1));
     97             }
     98         }
     99         bfs(zt);
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    Win8 iis 环境搭建
    Windows phone 8 触发器使用小结
    Windows Phone 页面之间参数传递方法
    日期SQL 脚本
    net 内存泄露和内存溢出
    Emacs的一些事情(与Vi的争议及使用)
    matlab与示波器连接及电脑连接
    msp430学习笔记-TA
    28个Unix/Linux的命令行神器
    linux在线中文手册
  • 原文地址:https://www.cnblogs.com/assult/p/4034548.html
Copyright © 2011-2022 走看看