hdu 5433 Xiao Ming climbing(优先队列+BFS)

题目链接

问题描述
小明因为受到大魔王的诅咒,被困到了一座荒无人烟的山上并无法脱离.这座山很奇怪:
这座山的底面是矩形的,而且矩形的每一小块都有一个特定的坐标(x,y)(x,y)(x,y)和一个高度HHH.
为了逃离这座山,小明必须找到大魔王,并消灭它以消除诅咒.
小明一开始有一个斗志值kkk,如果斗志为0则无法与大魔王战斗,也就意味着失败.
小明每一步都能从他现在的位置走到他的(N,E,S,W)(N,E,S,W)(N,E,S,W)四个位置中的一个,会消耗(abs(H1H2))/k(abs(H_1-H_2))/k(abs(H1H2))/k的体力,然后消耗一点斗志。
大魔王很强大,为了留下尽可能多的体力对付大魔王,小明需要找到一条消耗体力最少的路径.
你能帮助小明算出最少需要消耗的体力吗.
输入描述
第一行输入一个整数T(1T10)T( 1 \leq T \leq 10 )T(1T10)
接下来有TTTTTT组数据,每组数据有三个整数n,m,kn,m,kn,m,k含义如题(1n,m50,0k50)(1 \leq n,m \leq 50, 0 \leq k \leq 50)(1n,m50,0k50)
接下来有nnn行,每行mmm个字符,如果是数字则表示(i,j)(i,j)(i,j)的高度H(0H9)H(0 \leq H \leq 9)H(0H9),'#'表示障碍
最后两行分别输入小明的坐标(x1,y1)(x_1,y_1)(x1,y1)和大魔王的坐标(x2,y2)(x_2,y_2)(x2,y2),小明和魔王都不在障碍上。
输出描述
每组数据对应输出满足要求的体力(保留两位小数)。
如果无法逃离,则输出"No AnswerNo \ AnswerNo Answer"
输入样例
3
4 4 5
2134
2#23
2#22
2221
1 1
3 3
4 4 7
2134
2#23
2#22
2221
1 1
3 3
4 4 50
2#34
2#23
2#22
2#21
1 1
3 3
输出样例
1.03
0.00
No Answer

优先队列+bfs
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
const int f[4][2]={0,1,0,-1,1,0,-1,0};
double dis[52][52][52];
int n,m,K;
int sx,sy,ex,ey;
struct node
{
    double d;
    int x,y,k;
    bool operator < (const node &b) const
    {
        return d>b.d;
    }
};
char ma[52][52];
void bfs()
{
    priority_queue<node> q;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        for(int l=0;l<=K;l++)
        dis[i][j][l]=1e9;
    node st,en;
    st.x=sx,st.y=sy,st.k=K;
    st.d=0.0;
    dis[sx][sy][K]=0.0;
    q.push(st);
    while(q.size())
    {
        st=q.top();
        q.pop();
        for(int i=0;i<4;i++)
        {
            en.x=st.x+f[i][0];
            en.y=st.y+f[i][1];
            en.k=st.k-1;
            if(en.k<=0) continue;
            if(en.x>=0&&en.x<n&&en.y>=0&&en.y<m&&ma[en.x][en.y]!='#')
            {
                en.d=st.d+fabs((double)ma[en.x][en.y]-ma[st.x][st.y])/st.k;
                if(en.d<dis[en.x][en.y][en.k])
                {
                    dis[en.x][en.y][en.k]=en.d;
                    q.push(en);
                }
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&K);
        for(int i=0;i<n;i++)
            scanf("%s",ma[i]);
        scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
        sx--,sy--,ex--,ey--;
        bfs();
        double ans=1e9;
        for(int i=1;i<=K;i++)
            ans=min(ans,dis[ex][ey][i]);
        if(ans>1e8) puts("No Answer");
        else printf("%.2lf\n",ans);
    }
    return 0;
}

你可能感兴趣的:(优先队列,bfs,优先队列+bfs)