HDU 1548 A strange lift(Dijkstra,简单BFS)

题目大意:

    电梯有两个选项向上或向下,每层楼有一个参数ki,代表电梯可以再该楼层的基础上向上或向下移动ki层,限制条件是向上不能超过楼层总数n,向下不能少于一。输入总层数n和当前所在层数以及目标层数,然后是n个数分别代表第i层的移动范围。输出最少移动次数,若不可达,输出-1.

解题思路:

    1.用Dijkstra算法,首先构建邻接矩阵,注意在构造时,要考虑i-k[i]<1和i+k[i]>n,i代表当前所在层。

    

 1 #include<string.h>
 2 #include<stdio.h>
 3 #define INF 0x3f3f3f3f
 4 int k[201];
 5 int g[1001][1001];
 6 int dis[1001],vis[1001];
 7 int t,s,d,x,y;
 8 int a,b,n;
 9 void dijkstra(int start)
10 {
11     int i,j,k;
12     memset(vis,0,sizeof(vis));//初始化vis数组,标记为都未访问过。
13     for(i=1; i<=n; i++)
14     {
15         if(i==start)
16             dis[i]=0;
17         else
18             dis[i]=INF;
19     }//除起始点外,其他点的dis都赋为正无穷
20     for(i=1; i<=n; i++)
21     {
22         int r;
23         int min=INF;
24         for(j=1; j<=n; j++)
25             if(!vis[j]&&dis[j]<min)
26             {
27                 min=dis[j];
28                 r=j;
29             }找出当前未被访问的点中权值最小的点,对所有从该点出发的边进行松弛。
30         vis[r]=1;
31         for(k=1; k<=n; k++)//松弛操作
32             if(dis[k]<(dis[r]+g[r][k]))
33                 dis[k]=dis[k];
34             else
35                 dis[k]=dis[r]+g[r][k];
36     }
37     return;
38 }
39 int main()
40 {
41     int i;
42     while(scanf("%d",&n)!=EOF&&n)
43     {
44         memset(g,INF,sizeof(g));
45         scanf("%d%d",&a,&b);
46         for(i=1; i<=n; i++)
47         {
48             scanf("%d",&k[i]);
49         }
50         for(i=1; i<=n; i++)
51         {
52             if(i-k[i]<1)
53                 g[i][k[i]+i]=1;
54             if(i+k[i]>n)
55                 g[i][i-k[i]]=1;
56             if(i-k[i]>=1&&i+k[i]<=n)
57             {
58                 g[i][k[i]+i]=1;
59                 g[i][i-k[i]]=1;
60             }
61         }
62         dijkstra(a);
63         if(dis[b]==INF)
64             printf("-1\n");
65         else
66             printf("%d\n",dis[b]);
67     }
68     return 0;
69 }

   2.BFS算法:

         有向上走和向下走两种方法:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <queue>
 4 using namespace std;
 5 int n, start,end;
 6 int a[205];
 7 bool vis[205], flag;
 8 struct node
 9 {
10     int x, step;//x记录当前所在层,step记录已经走了几次
11 } n1, n2, m;
12 int main()
13 {
14     int i;
15     while(scanf("%d", &n)!=EOF)
16     {
17         if(n== 0)
18             break;
19         scanf("%d %d", &start,&end);
20         for(i = 1; i <= n; i++)
21         {
22             scanf("%d", &a[i]);
23             vis[i] = false;
24         }
25         flag = false;
26         n1.x = start;
27         n1.step = 0;
28         queue<node> Q;
29         Q.push(n1);//起始点入队列
30         vis[n1.x] = true;
31         while(!Q.empty())
32         {
33             m = Q.front();
34             Q.pop();
35             if(m.x == end)
36             {
37                 flag = true;
38                 break;
39             }
40             n1.x = m.x - a[m.x];
41             n2.x = m.x + a[m.x];
42             if(n1.x>0 && n1.x<=end && !vis[n1.x])
43             {
44                 n1.step = m.step + 1;
45                 vis[n1.x] = true;
46                 Q.push(n1);
47             }
48             if(n2.x>0 && n2.x<=end && !vis[n2.x])
49             {
50                 n2.step = m.step + 1;
51                 vis[n2.x] = true;
52                 Q.push(n2);
53             }
54         }
55         if(flag)
56             printf("%d\n", m.step);
57         else
58         printf("-1\n");
59     }
60     return 0;
61 }
posted @ 2014-07-24 09:30  PJQOOO  阅读(344)  评论(0编辑  收藏  举报