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 94 95
| #include<iostream> #include<vector> #include<climits> #include<string> #include<queue> using namespace std; #define lu(i,j) ((i-1)*(n+1)+j) #define ru(i,j) ((i-1)*(n+1)+j+1) #define ld(i,j) (i*(n+1)+j) #define rd(i,j) (i*(n+1)+j+1) #define ALL (501*501+1) struct twice { int point, weight; }; struct Node { vector<twice> next; }; struct Nodep { int dis, id; bool operator<(const Nodep&r)const { return dis > r.dis; } }; Node edge[ALL]; int dis[ALL]; int vis[ALL]; inline void reset(int&m, int&n) { for (int i = 1; i <= rd(m, n); i++) dis[i] = INT_MAX, vis[i] = 0, edge[i].next.clear(); } inline void f(int&m, int&n, int&i, int j, int k) { j++; edge[lu(i, j)].next.push_back({ rd(i,j),k }); edge[rd(i, j)].next.push_back({ lu(i,j),k }); edge[ru(i, j)].next.push_back({ ld(i,j),!k }); edge[ld(i, j)].next.push_back({ ru(i,j),!k }); } inline void build(int&m, int&n) { for (int i = 1; i <= m; i++) { register string t; cin >> t; for (int j = 0; j < n; j++) { (t[j] == '\\') ? f(m, n, i, j, 0) : f(m, n, i, j, 1); } } } inline int dijstra(int&m, int&n) { register priority_queue<Nodep> edgep; register int now = 1, end = rd(m, n); dis[now] = 0; edgep.push({ 0,1 }); while (!edgep.empty()) { now = edgep.top().id; edgep.pop(); if (vis[now])continue; vis[now] = 1; for (int e = 0; e < edge[now].next.size(); e++) { register int &ep = edge[now].next[e].point, &ew = edge[now].next[e].weight; if (dis[ep] > dis[now] + ew) { dis[ep] = dis[now] + ew; if (!vis[ep]) edgep.push(Nodep{ dis[ep],ep }); } } } return dis[end]; } int main() { ios::sync_with_stdio(false); int T; int m, n; cin >> T; while (T--) { cin >> m >> n; reset(m, n); build(m, n); int ans = dijstra(m, n); if (ans == INT_MAX)cout << "NO SOLUTION" << endl; else cout << ans << endl; } return 0; }
|