1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <bits/stdc++.h> #include <ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; #define tar(i,n) for(int i=1;i<=n;++i) const int N = 105; const double eps = 1e-7; double L; int R, C; char mymap[N][N]; int pos[N][N]; int S, T, Tim; typedef __gnu_pbds::priority_queue <pair<double, int>, greater<pair<double, int> >, pairing_heap_tag> heap; struct node { int next, to; bool flag; } edge[50005]; int first[10005], tot; inline void Tjb(int x, int y, bool _flag) { edge[++tot].to = y; edge[tot].flag = _flag; edge[tot].next = first[x]; first[x] = tot; }
inline void lql() { memset(first, 0, sizeof(first)); tot = 0; }
double Dist[10005]; inline double dijkstra(double X) { heap q; vector<heap::point_iterator> id; id.reserve(1000005); tar(i, R * C)Dist[i] = 5000.0; Dist[S] = 0.0; q.push(make_pair(Dist[S], S)); while (!q.empty()) { int u = q.top().second; q.pop(); for (int k = first[u]; k; k = edge[k].next) { int v = edge[k].to; if (edge[k].flag) { if (Dist[v] > Dist[u] + X) { Dist[v] = Dist[u] + X; if (id[v] != 0) q.modify(id[v], make_pair(Dist[v], v)); else id[v] = q.push(make_pair(Dist[v], v)); } } else { if (Dist[v] > Dist[u] + 1) { Dist[v] = Dist[u] + 1; if (id[v] != 0) q.modify(id[v], make_pair(Dist[v], v)); else id[v] = q.push(make_pair(Dist[v], v)); } } } } return Dist[T]; } inline void Test() { lql(); scanf("%lf%d%d\n", &L, &R, &C); Tim = 0; tar(i, R) { tar(j, C)mymap[i][j] = getchar(); scanf("\n"); }
tar(i, R)tar(j, C)if (mymap[i][j] != '#') { pos[i][j] = ++Tim; if (mymap[i][j] == 'S')S = pos[i][j]; else if (mymap[i][j] == 'E')T = pos[i][j]; }
tar(i, R)tar(j, C)if (mymap[i][j] != '#') { if (i != 1 && mymap[i - 1][j] != '#')Tjb(pos[i][j], pos[i - 1][j], true); if (i != R && mymap[i + 1][j] != '#')Tjb(pos[i][j], pos[i + 1][j], true); if (j != 1 && mymap[i][j - 1] != '#')Tjb(pos[i][j], pos[i][j - 1], false); if (j != R && mymap[i][j + 1] != '#')Tjb(pos[i][j], pos[i][j + 1], false); }
double l = 0.0, r = 10.0, ans = 0.0; while (r - l > eps) { double mid = (l + r) / 2; if (dijkstra(mid) < L)ans = mid, l = mid; else r = mid; }
printf("%.5lf\n", ans); }
int main() { int times; scanf("%d", ×); while (times--)Test(); return 0; }
|