开始做这题的时候总是将它和最小生成树算法混淆,最短路径初始的时候是存的从其点到其他各点的距离,没有的设为无穷,每次都是找出最短的路径值(同时标记该顶点,说明已经找到了最短的路径,不需要再修改),并且不断修改起点到其他各点的距离,如此循环,知知道所有顶点都访问;
//思路:本质是找从 A 到 B 的最短路径,如果最短路径存在则一定会用满足题意的按最少次数的按钮
//如果最短路径不存在肯定找不到,输出  -1 
//这里将可以到达的点设为 1, 是因为如果可以到达就按了一下按钮,如果不可到达则仍然是MAX 
//此题中如果有某一个点找不到到达它的最短路径,说明电梯到达这一层之后不可能再达到其他任何了,所以return返回主函数检查;这是和模板不同的地方
 #include <iostream>
#include <iostream>
 #include <string>
#include <string>
 using namespace std;
using namespace std;

 #define MAXN 99999999
#define MAXN 99999999
 int button[201];        //存储每一层按下按钮之后可升降的层数
int button[201];        //存储每一层按下按钮之后可升降的层数
 int map[201][201];
int map[201][201]; 

 int dist[201];
int dist[201];
 int visit[201];
int visit[201];
 int n, a, b;
int n, a, b;

 void dijkstra ()
void dijkstra ()


 {
{
 for (int i = 1; i <= n; i ++)
    for (int i = 1; i <= n; i ++)

 
     {
{
 dist[i] = map[a][i];                     //初值是起点到每个点的距离!
        dist[i] = map[a][i];                     //初值是起点到每个点的距离!
 }
    }
 
    
 dist[a] = 0;
    dist[a] = 0;
 
    
 int k, min;
    int k, min;
 for ( int i = 1; i <= n; i ++ )
    for ( int i = 1; i <= n; i ++ )

 
     {
{        
 min = MAXN;
        min = MAXN;
 for (int j = 1; j <= n; j ++)
        for (int j = 1; j <= n; j ++)

 
         {
{
 if ( !visit[j] && dist[j] < min )                  //找最短的距离
            if ( !visit[j] && dist[j] < min )                  //找最短的距离                           

 
             {
{
 min = dist[j];
                 min = dist[j]; 
 k = j;
                 k = j;                                                                                                                                 
 }
            }
 }
        }
 
       
 if ( min == MAXN )   //没有最短路了             // 顺序
       if ( min == MAXN )   //没有最短路了             // 顺序
 return ;
           return ;
 visit[k] = 1;
       visit[k] = 1;
 
       
 
           
 for (int j = 1; j <= n; j ++)
        for (int j = 1; j <= n; j ++)

 
         {
{
 if ( !visit[j] && map[k][j] + dist[k] < dist[j] )
            if ( !visit[j] && map[k][j] + dist[k] < dist[j] )

 
             {
{
 dist[j] = map[k][j] + dist[k];
                 dist[j] = map[k][j] + dist[k];
 }
            }
 }
        }
 }
    }  
 }
}

 int main ()
int main ()


 {
{
 
    
 while ( scanf ("%d", &n) != EOF && n )
    while ( scanf ("%d", &n) != EOF && n )

 
     {
{
 scanf ( "%d %d", &a, &b );
          scanf ( "%d %d", &a, &b );
 
          
 memset ( button, 0, sizeof (button) );
          memset ( button, 0, sizeof (button) );
 memset ( dist, 0, sizeof (dist) );
          memset ( dist, 0, sizeof (dist) );
 memset ( visit, 0, sizeof (visit) );
          memset ( visit, 0, sizeof (visit) );
 
          
 for ( int i = 1; i <= n; i ++ )
          for ( int i = 1; i <= n; i ++ )

 
           {
{
 for ( int j = 1; j <= n; j ++ )
              for ( int j = 1; j <= n; j ++ )

 
               {
{
 map[i][j] = MAXN;
                  map[i][j] = MAXN;
 }
              }
 }
          }
 
          
 for ( int i = 1; i <= n; i ++ )
          for ( int i = 1; i <= n; i ++ )

 
           {
{
 scanf ("%d", &button[i]);
              scanf ("%d", &button[i]);
 if ( i + button[i] <= n )
              if ( i + button[i] <= n )

 
               {
{
 map[i][i + button[i]] = 1;
                   map[i][i + button[i]] = 1;
 }
              }
 if ( i - button[i] >= 1 )    //最大的错误不是else if啊!!!!
              if ( i - button[i] >= 1 )    //最大的错误不是else if啊!!!! 

 
               {
{
 map[i][i - button[i]] = 1;
                   map[i][i - button[i]] = 1;
 }
              }
 }
          }
 
          
 dijkstra ();
          dijkstra ();
 
          
 if ( dist[b] < MAXN )               //有路径到达
          if ( dist[b] < MAXN )               //有路径到达
 printf ("%d\n", dist[b]);
          printf ("%d\n", dist[b]);
 else
          else
 printf ("%d\n", -1);
          printf ("%d\n", -1);
 
          
 }
    }

 //system ("pause");
     //system ("pause");
 return 0;
     return 0;
 }
}

posted on 2010-08-26 20:38 
雪黛依梦 阅读(403) 
评论(0)  编辑 收藏 引用  所属分类: 
最小生成树