思路
我们可以把整个电路系统想成是一个无向图,如果从点\(A(x_1,y_1)到B(x_2,y_2)\)且这个路上的方格的电路时符合走向的,那么认定这条路的边权为\(0\),如果与走向相悖,那么边权为\(1\)。为了做一个合理的优化,我们可以使用双端队列,优先处理边权为\(0\)的边,然后确保每个点只经过一次即可。复杂度比较低,看代码吧。
// CH2601.cpp #include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cstring> #define pr pair<int, int> #define ppr pair<int, pr> using namespace std; const int maxn = 510, dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, 1, -1}, INF = 0x3f3f3f3f; const char sym[4] = {'\\', '/', '\\', '/'}; int T, N, M, dist[maxn][maxn]; char map[maxn][maxn]; bool validiate(int x, int y) { return x > 0 && x <= N + 1 && y > 0 && y <= M + 1; } int main() { scanf("%d", &T); while (T--) { memset(dist, 0x3f, sizeof(dist)); scanf("%d%d", &N, &M); for (int i = 1; i <= N; i++) scanf("%s", map[i] + 1); deque<ppr> qpool; qpool.push_back(make_pair(0, make_pair(1, 1))); while (!qpool.empty()) { ppr curt = qpool.front(); int x = curt.second.first, y = curt.second.second, k = curt.first; qpool.pop_front(); if (dist[x][y] != INF) continue; dist[x][y] = k; for (int i = 0; i < 4; i++) { int a = x + dx[i], b = y + dy[i]; if (validiate(a, b) && dist[a][b] == INF) { if (sym[i] == map[min(a, x)][min(b, y)]) qpool.push_front(make_pair(k, make_pair(a, b))); else qpool.push_back(make_pair(k + 1, make_pair(a, b))); } } } if (dist[N][M] == INF) printf("NO SOLUTION\n"); else printf("%d\n", dist[N + 1][M + 1]); } return 0; }