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

2 years ago
#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;
}