hdu 2425 Hiking Trip (dfs)

HDU 2425 Hiking Trip (dfs)

http://acm.hdu.edu.cn/showproblem.php?pid=2425

//题目的意思大概就是要我们找一条从(sc,sr)(tc,tr)的路径使得时间最少

//这一点就是和别的题目不太一样了,因为我们一般bfs都是以步数为标准的,

//而且都是+1的,这里要每一次把队列以时间为标准排一下序

//要谢谢我们吴老板给我们的这个Stl

/*

优先队列priority_queue:(自动排列的队列)

 

  struct node

  {

  friend bool operator< (node n1, node n2)

  {

  return n1.time < n2.time;

  }

  int i,j;

  int time;

  };

  priority_queue<node, vector<node>, greater<node> >q;

  其中

  第二个参数为容器类型。

  第三个参数为比较函数。

*/

#include<iostream>

#include<queue>

#include<cmath>

using namespace std;

char map[22][22]; //地图

int visit[22][22]; //标记是否走过

int dir[][2]={0,1,1,0,-1,0,0,-1};//四个方向

struct node

{

       friend bool operator> (node n1, node n2) //这里是<的时候编译不过,不解T_T...

       {

              return n1.time > n2.time;

       }    

       int x,y;

       int time;

};

int cases,i,j;

int r,c;

int vp,vs,vt;   //三种字符要用的时间

int sc,sr,tc,tr;  //起点和终点

int stone;

void bfs();

int main()

{

       cases=0;

       while(scanf("%d%d",&r,&c)!=EOF)

       {

              cases++;

              stone=0;

              scanf("%d%d%d",&vp,&vs,&vt);

              getchar(); // 吃掉回车

              for(i=0;i<r;i++)

              {

                     for(j=0;j<c;j++)

                     {

                            scanf("%c",&map[i][j]);

                            if(map[i][j]=='@')

                            {

                                   stone++;    // 统计石头,剪枝

                            }

                            visit[i][j]=0;

                     }

                            getchar();//每行吃掉回车

              }

              scanf("%d%d%d%d",&sr,&sc,&tr,&tc);

              if(abs(sr-tr)+abs(sc-tc)+stone>=r*c)//剪枝

              {

                     printf("Case %d: %d/n",cases,-1);

                     continue;

              }

              bfs();

       }

       return 0;

}

void bfs()

{

       if(sr==tr&&sc==tc)

       {

                     printf("Case %d: %d/n",cases,0);

                     return ;

       }

       node start;

       start.x=sr;

       start.y=sc;

       start.time=0;

       priority_queue< node,vector<node>,greater<node> > q;

       //关键一步,因为入队之后要对时间小的先操作,来自Stl,学习了

       q.push(start);

       visit[sr][sc]++;

       node t,temp;

       while(!q.empty())

       {

              t=q.top();

              q.pop();

              for(i=0;i<4;i++)

              {

                     temp=t;

                     temp.x+=dir[i][0];

                     temp.y+=dir[i][1];

                     if(temp.x>=r||temp.x<0 || temp.y>=c||temp.y<0 ||

 map[temp.x][temp.y]=='@' ||

 visit[temp.x][temp.y]>0)

                     //判断边界、是不是石头、是不是用过了

                     {

                            continue;

                     }

                     switch(map[temp.x][temp.y])           //计算时间变化

                     {

                     case '#': temp.time += vp; break; 

                     case '.': temp.time += vs; break; 

                     case 'T': temp.time += vt; break; 

                     }

                     if (temp.x == tr && temp.y == tc)   //找到目标

                     {

                            printf("Case %d: %d/n", cases, temp.time); 

                            return;

                     }

                     else //入队

                     {

                            q.push(temp);

                            visit[temp.x][temp.y] ++;

                     }

 

              }

 

       }

       printf("Case %d: %d/n", cases, -1);

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值