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

来源:互联网 发布:ff14高地男捏脸数据 编辑:程序博客网 时间:2024/06/11 11:18


题意:电梯每层有一个不同的数字,例如第n层有个数字k,那么这一层只能上k层或下k层,但是不能低于一层或高于n层,      给定起点与终点,要求出最少要按几次键。思路:此题较为简单,只有两个方向,那么抽象为二叉树。又因为所找的目标节点已知,且要求最短路,因此将所有情况
      记录下来,满足宽度优先原则。代码实现:

方法二:
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <algorithm>  
  4. #include <queue>  
  5. using namespace std;  
  6.   
  7. int n,s,e;  
  8. int ss[205],vis[205];  
  9.   
  10. struct node  
  11. {  
  12.     int x,step;  
  13. };  
  14.   
  15. int check(int x)  
  16. {  
  17.     if(x<=0 || x>n)  
  18.     return 1;  
  19.     return 0;  
  20. }  
  21.   
  22. int BFS()  
  23. {  
  24.     queue<node> Q;  
  25.     node a,next;  
  26.     int i;  
  27.     a.x = s;  
  28.     a.step = 0;  
  29.     vis[s] = 1;  
  30.     Q.push(a);  
  31.     while(!Q.empty())  
  32.     {  
  33.         a = Q.front();  
  34.         Q.pop();  
  35.         if(a.x == e)  
  36.         return a.step;  
  37.         for(i = -1;i<=1;i+=2)  
  38.         {  
  39.             next = a;  
  40.             next.x +=i*ss[next.x];  
  41.             if(check(next.x) || vis[next.x])  
  42.             continue;  
  43.             vis[next.x] = 1;  
  44.             next.step++;  
  45.             Q.push(next);  
  46.         }  
  47.     }  
  48.     return -1;  
  49. }  
  50.   
  51. int main()  
  52. {  
  53.     int i,j;  
  54.     while(~scanf("%d",&n),n)  
  55.     {  
  56.         scanf("%d%d",&s,&e);  
  57.         for(i = 1;i<=n;i++)  
  58.         scanf("%d",&ss[i]);  
  59.         memset(vis,0,sizeof(vis));  
  60.         printf("%d\n",BFS());  
  61.     }  
  62.   
  63.     return 0;  
  64. }

方法三:

一开始的想法是搜索,而且搜索也是可行的,不过既然这道题出在了最短路的专题里面,自然也要尝试下最短路的做法,
要注意的是,这道题是单向边,我们只要让map里面的值全部为1就可以统计次数了
 
最短路的Dijkstra
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <algorithm>  
  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<n; i++)  
  18.         cast[i] = map[s][i];  
  19.     cast[s] = 0;  
  20.     vis[s] = 1;  
  21.     for(i = 1; i<n; i++)  
  22.     {  
  23.         min = inf;  
  24.         for(j = 0; j<n; j++)  
  25.         {  
  26.             if(cast[j]<min && !vis[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<n; j++)  
  36.         {  
  37.             if(cast[pos]+map[pos][j]<cast[j] && !vis[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<n; i++)  
  51.             for(j = 0; j<n; j++)  
  52.                 map[i][j] = inf;  
  53.         for(i = 0; i<n; i++)  
  54.         {  
  55.             scanf("%d",&a[i]);  
  56.             if(i+a[i]<n)  
  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<stdio.h>#include<string.h>#define M 1000000int 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<n;i++){  min=M;  for(j=1;j<=n;j++){//选最短路径   if(!mark[j]&&dis[j]<min){    min=dis[j];    d=j;     f(min==M)//没有最短路径了,可以返回,当然不返回也行,效率低点   return;  mark[d]=1;//把已选的标记  for(j=1;j<=n;j++)   if(!mark[j]&&cost[d][j]+dis[d]<dis[j])//核心:有点像状态转移方程    dis[j]=dis[d]+cost[d][j]; }}

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]<M) //如果没有到达   printf("%d\n",dis[b]);  else   puts("-1"); return 0;}




0 0
原创粉丝点击