12709:[Violet 1]迷宫花园

#include <bits/stdc++.h>
#define INF 1000000000
using namespace std;
int r, c;
double ll;
char mp[110][110];
int get(int rr, int cc)
{
    return (rr - 1) * c + cc;
}
int dr[4] = {1, -1, 0, 0}, dc[4] = {0, 0, 1, -1};
vector <int> bi[10010];
vector <double> ci[10010];
int s, e;
void build(int a, int b, double c)
{
    bi[a].push_back(b); ci[a].push_back(c);
    bi[b].push_back(a); ci[b].push_back(c);
}
struct node
{
    int t; double l;
};
bool operator < (node a, node b) {return a.l > b.l;}
priority_queue <node> H;
int vis[10010]; double dis[10010];
int main()
{
    int T;
    cin >> T;
    while (T --)
    {
        cin >> ll >> r >> c;
        for (int i = 1; i <= r; i++)  
        {  
            char cc;  
            scanf("%c", &cc);  
            while (cc != '\n') scanf("%c", &cc);  
            for (int j = 1; j <= c; j++)  
            {  
                scanf("%c", &cc);  
                while (cc == '\n') scanf("%c",&cc);
                mp[i][j] = cc;
                if (cc=='S') s = get(i, j);
                if (cc=='E') e = get(i, j);
            }  
        }  
        {
            double lb = 0, rb = 10;
            while (rb - lb > 0.0000001)
            {
                double md = (lb + rb) / 2;
                for (int i = 1; i <= r * c; ++ i) bi[i].clear(), ci[i].clear();
                for (int i = 1; i <= r; ++ i)
                    for (int j = 1; j <= c; ++ j)
                        for (int d = 0; d < 4; ++ d)
                            if (mp[i][j] != '#' && mp[i + dr[d]][j + dc[d]] != '#')
                                build(get(i, j), get(i + dr[d], j + dc[d]), (d >= 2? 1: md));
                for (int i = 1; i <= r * c; ++ i)
                    dis[i] = INF, vis[i] = 0;
                while (!H.empty()) H.pop();
                dis[s] = 0,
                H.push((node){s, 0});
                while (!H.empty())
                {
                    int hd;
                    do hd = H.top().t, H.pop();
                    while (vis[hd] && !H.empty()); 
                    if (!vis[hd]) vis[hd] = 1;
                    else break;
                    for (int i = 0; i < bi[hd].size(); ++ i)
                        if (dis[hd] + ci[hd][i] < dis[bi[hd][i]])
                        {
                            dis[bi[hd][i]] = dis[hd] + ci[hd][i];
                            H.push((node){bi[hd][i], dis[bi[hd][i]]});
                        }
                }
                if (dis[e] > ll) rb = md;
                else lb = md;
            }
            printf("%.5lf\n", lb);
        }
                                      
    }
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值