Hdu 1548 A strange lift

题意:

有一个建筑有N层,里面有一架电梯。给你一个起点层数和一个终点层数。在每一层都有一个按钮,按钮上面有一个数字,表示可以上或者下Ki层。然后你可以由起点开始选择上或者下(重复……),当你到达终点为止(或者不可能到达终点为止)。求你需要按按钮的次数,不能到达则输出-1。

 

思路:

这道题可以转换为一道最短路题目,对第i层,按钮数字为k[i],则如果满足相加<=N,则把i到i+k[i]的路径长度设为1(巧妙将按钮次数转换为路径长度),同理,相减如果满足>=1,则把i到i-k[i]的路径长度设为1.则最后输出终点的最短路的长度即可。

 

注意:

(1)有向图。

(2)可走的范围别越界。

CODE:

 

#include <stdio.h>
#include <stdlib.h>
#include < string.h>
using  namespace std;

const  int SIZE =  1001;
const  int INF =  0x3f3f3f3f;
int w[SIZE][SIZE];
int d[SIZE], v[SIZE];
int k[SIZE];
int n;

void Dijkstra( int s)
{
     int i, j;
     for(i =  1; i <= n; i++) d[i] = (i == s)?  0:INF;
     for(i =  1; i <= n ;i++)
    {
         int x, m = INF;
         for( int y =  1; y <= n; y++)  if(!v[y] && m > d[y]) m = d[x=y];
         if(m == INF)  break;
        v[x] =  1;
         for( int y =  1; y <= n; y++) d[y] <?= d[x] + w[x][y];
    }
     return ;
}


void init()
{
    memset(w, INF,  sizeof(w));
    memset(d,  0sizeof(d));
    memset(v,  0sizeof(v));
    memset(k,  0sizeof(k));
}


int main()
{
     int i, j;
     int s, e;
     while(~scanf( " %d ", &n), n)
    {
        init();
        scanf( " %d%d ", &s, &e);
         for(i =  1; i <= n; i++)
        {
            scanf( " %d ", &k[i]);
             if(k[i]+i <= n) w[i][k[i]+i] =  1;
             if(i-k[i] >=  1) w[i][i-k[i]] =  1;
        }
        Dijkstra(s);
         if(d[e] == INF) printf( " -1\n ");
         else printf( " %d\n ", d[e]);
    }
     return  0;
}

 

你可能感兴趣的:(HDU)