You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
2.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 110, INF = 0x3f3f3f3f;
int n, m;
int g[N][N]; // 原始地图
int d[N][N]; // 记录最短距离,这个东西的作用是用来进行最优化剪枝,这个非常妙
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
void dfs(int x, int y, int cost, int used) {
if (d[x][y] <= cost) return; // 最优化剪枝,排除非最优路线
d[x][y] = cost; // 记录最优路线花费
if (x == m && y == m) return; // 递归出口
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = dy[i] + y;
if (nx < 1 || nx > m || ny < 1 || ny > m) continue;
if (g[nx][ny] == -1) { // 下一个位置是无色
if (used) continue; // 当前位置已使过魔法,下一个就无法继续使用魔法,无色不能变有色,无效
// 如果当前位置没有使用过魔法的话,下一个位置是可以使用魔法的,那么变成什么颜色呢?
// 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为 你当前所处格子的颜色
g[nx][ny] = g[x][y];
dfs(nx, ny, cost + 2, 1); // 走入这个(nx,ny),标识费用+2同时标注(nx,ny)的魔法是已使用状态,继续传递
g[nx][ny] = -1; // 也可以不走这个(nx,ny),需要回溯
} else if (g[nx][ny] == g[x][y]) // 下一个位置颜色相同
dfs(nx, ny, cost, 0); // 直接走过去,费用不变,也没有使用魔法
else
dfs(nx, ny, cost + 1, 0); // 有色到有色颜色不同花费1个金币没有使用魔法
}
}
int main() {
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
cin >> m >> n;
memset(g, -1, sizeof g); // 标识无色是-1
while (n--) {
int a, b, c;
cin >> a >> b >> c;
g[a][b] = c; // 有颜色你就说是啥颜色吧
}
memset(d, 0x3f, sizeof d);
dfs(1, 1, 0, 0);
if (d[m][m] == INF)
puts("-1");
else
cout << d[m][m] << endl;
return 0;
}