HDU 1548---A strange lift(搜索&&最短路)

HDU 1548---A strange lift(搜索&&最短路)_第1张图片


题意:电梯每层有一个不同的数字,例如第n层有个数字k,那么这一层只能上k层或下k层,但是不能低于一层或高于n层,
      给定起点与终点,要求出最少要按几次键。

思路:此题较为简单,只有两个方向,那么抽象为二叉树。又因为所找的目标节点已知,且要求最短路,因此将所有情况
      记录下来,满足宽度优先原则。


代码实现:


 
  
方法二:
 
  #include    
  #include    
  #include    
  #include    
  using namespace std;   
     
  int n,s,e;   
  int ss[205],vis[205];   
     
  struct node   
  {   
      int x,step;   
  };   
     
  int check(int x)   
  {   
      if(x<=0 || x>n)   
      return 1;   
      return 0;   
  }   
     
  int BFS()   
  {   
      queue Q;   
      node a,next;   
      int i;   
      a.x = s;   
      a.step = 0;   
      vis[s] = 1;   
      Q.push(a);   
      while(!Q.empty())   
      {   
          a = Q.front();   
          Q.pop();   
          if(a.x == e)   
          return a.step;   
          for(i = -1;i<=1;i+=2)   
          {   
              next = a;   
              next.x +=i*ss[next.x];   
              if(check(next.x) || vis[next.x])   
              continue;   
              vis[next.x] = 1;   
              next.step++;   
              Q.push(next);   
          }   
      }   
      return -1;   
  }   
     
  int main()   
  {   
      int i,j;   
      while(~scanf("%d",&n),n)   
      {   
          scanf("%d%d",&s,&e);   
          for(i = 1;i<=n;i++)   
          scanf("%d",&ss[i]);   
          memset(vis,0,sizeof(vis));   
          printf("%d\n",BFS());   
      }   
     
      return 0;   
  }  
  
方法三:

一开始的想法是搜索,而且搜索也是可行的,不过既然这道题出在了最短路的专题里面,自然也要尝试下最短路的做法,
要注意的是, 这道题是单向边,我们只要让map里面的值全部为1就可以统计次数了
 
最短路的Dijkstra
 
  
  1. #include   
  2. #include   
  3. #include   
  4. using namespace std;  
  5.   
  6. const int inf = 1<<30;  
  7.   
  8. int n;  
  9. int map[205][205];  
  10. int a[205],cnt;  
  11. int vis[205],cast[205];  
  12.   
  13. void Dijkstra(int s,int e)  
  14. {  
  15.     int i,j,min,pos;  
  16.     memset(vis,0,sizeof(vis));  
  17.     for(i = 0; i
  18.         cast[i] = map[s][i];  
  19.     cast[s] = 0;  
  20.     vis[s] = 1;  
  21.     for(i = 1; i
  22.     {  
  23.         min = inf;  
  24.         for(j = 0; j
  25.         {  
  26.             if(cast[j]
  27.             {  
  28.                 pos = j;  
  29.                 min = cast[j];  
  30.             }  
  31.         }  
  32.         if(min == inf)  
  33.             break;  
  34.         vis[pos] = 1;  
  35.         for(j = 0; j
  36.         {  
  37.             if(cast[pos]+map[pos][j]
  38.                 cast[j] = cast[pos]+map[pos][j];  
  39.         }  
  40.     }  
  41. }  
  42.   
  43. int main()  
  44. {  
  45.     int i,j,s,e,x,y;  
  46.     while(~scanf("%d",&n),n)  
  47.     {  
  48.         scanf("%d%d",&s,&e);  
  49.         s--,e--;  
  50.         for(i = 0; i
  51.             for(j = 0; j
  52.                 map[i][j] = inf;  
  53.         for(i = 0; i
  54.         {  
  55.             scanf("%d",&a[i]);  
  56.             if(i+a[i]
  57.                 map[i][i+a[i]] = 1;  
  58.             if(i-a[i]>=0)  
  59.                 map[i][i-a[i]] = 1;  
  60.         }  
  61.         Dijkstra(s,e);  
  62.         printf("%d\n",cast[e]==inf?-1:cast[e]);  
  63.     }  
  64.   
  65.     return 0;  

另一种Dijkstra代码:

 
  

#include #include #define M 1000000 int n,a,b,dis[201],cost[202][201];

void dijkstra() {  int i,j,d,min,mark[201];  for(i=1;i<=n;i++)   dis[i]=cost[a][i]; //dis[i]代表源点到i点的距离  memset(mark,0,sizeof(mark)); //标记数组初始化  dis[a]=0;//到本身距离为0  for(i=1;i

int main() {  int i,j,k[201];  while(scanf("%d",&n),n){   scanf("%d%d",&a,&b);   for(i=1;i<=n;i++){    for(j=1;j<=n;j++)     cost[i][j]=M; //初始距离默认为无穷大   }   for(i=1;i<=n;i++){    scanf("%d",&k[i]);    if(i+k[i]<=n) //合法才处理     cost[i][i+k[i]]=1; //这就是对应能到的层数    if(i-k[i]>=1)     cost[i][i-k[i]]=1;   }   dijkstra();   if(dis[b]


 
   
  

你可能感兴趣的:(搜索,二叉树,搜索)