hdu 5433 Xiao Ming climbing

题意:一张图,给出起点和终点,给一个fighting值,每走一步fighting消耗1,并且消耗(abs(H1H2))/fighting 的 physical power。求起点到终点消耗最小的physical pow。

解:题目上有一句"At the biginning Xiao Ming has a fighting will k,if it turned to 0 Xiao Ming won't be able to fight with the devil,that means failure.",原来到终点的时候fighting值可以为0,昨天这里错了一晚上。

思路:优先队列或者普通bfs都可以,这里用优先队列实现。

#include <iostream>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>

using namespace std;


typedef unsigned int uint;
typedef long long LL;
typedef unsigned long long uLL;

const int N = 55;
const double PI = acos(-1.0);
const double eps = 1e-6;
const double INF = 1e9+7;

int n, m, k;
double csm_ft;

char mp[N][N];

struct pt {
    int x, y;
    pt(){}
    pt(int _x, int _y):x(_x), y(_y) {}
    pt operator + (const pt& add) {
        return pt(this->x + add.x, this->y + add.y);
    }
    bool operator == (const pt& eq) {
        return (this->x == eq.x && this->y == eq.y);
    }
};

struct node {
public:
    pt p;
    int ft;
    double csm;
    node(){}
    node(pt _p, int _ft, double _csm):p(_p), ft(_ft), csm(_csm) {}
    bool operator < (const node& cmp) const {
        //return ft < cmp.ft;
        return csm > cmp.csm;
    }
};

priority_queue <node> q;

pt bg, ed;

double vis[N][N][N];

pt dir[4] = {pt(1, 0), pt(-1, 0), pt(0, 1), pt(0, -1)};

bool in_bound(pt p){
    return (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m);
}

double bfs(int k) {
    while(!q.empty())   q.pop();

    q.push(node(bg, k, 0));
    vis[bg.x][bg.y][k] = 0.0f;

    pt _tp;
    double s_csm, ans = INF;
    node t;

    while(!q.empty()){
        t = q.top();
        q.pop();

        if(t.ft <= 0)   continue;

        if(t.p == ed) {
            ans = min(ans, t.csm);
            continue;
        }
        for(auto d : dir) {
            _tp = t.p + d;
            if(!in_bound(_tp) || mp[_tp.x][_tp.y] == '#')  continue;

            s_csm = abs(mp[_tp.x][_tp.y] - mp[t.p.x][t.p.y]) * 1. / t.ft;
            //vis[_tp.x][_tp.y] = min(vis[_tp.x][_tp.y], t.csm);
            if(t.csm + s_csm >= vis[_tp.x][_tp.y][t.ft - 1])  continue;

            vis[_tp.x][_tp.y][t.ft - 1] = t.csm + s_csm;
            q.push(node(_tp, t.ft - 1, t.csm + s_csm));
            //printf("%d %d %d %f\n", _tp.x, _tp.y, t.ft - 1, t.csm + s_csm);
        }
    }

    return ans;
}

int main(){
    //freopen("data.in", "r", stdin);
    int T;
    cin >> T;
    while(T--){
        cin >> n >> m >> k;
        for(int i = 0; i < n; ++i) {
            scanf("%s", mp[i]);
            for(int j = 0; j < m; ++j) {
                for(int l = 0; l <= k; ++l) {
                    vis[i][j][l] = INF;
                }
            }
        }
        scanf("%d%d", &bg.x, &bg.y);
        scanf("%d%d", &ed.x, &ed.y);
        bg.x--;
        bg.y--;
        ed.x--;
        ed.y--;
        double ans = bfs(k);
        if(ans >= INF) puts("No Answer");
        else    printf("%.2f\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2015-09-19 19:18  hi_coder  阅读(103)  评论(0编辑  收藏  举报