Sol
如果两个点相邻,那么边权为 \(1\)。
如果两个点能通过一次操作来联通,此时这两个点一定满足 \(x\) 或者 \(y\) 的差小于等于 \(2\)(手摸一下就知道了),此时边权为 \(1\)。
其他情况边权就是 \(+\infty\)。
直接跑最短路,时间复杂度 \(O(k^2)\)。
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {if (y > x) return x = y,true;return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {if (y < x) return x = y,true;return false;
}
LL power (LL a,LL b,LL p) {LL ans = 1;while (b) {if (b & 1) ans = ans * a % p;a = a * a % p;b >>= 1;}return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 10010;
int n,m,k;
PII a[N];
int dist[N];
int get_w (int i,int j) {int dx = abs (a[i].x - a[j].x),dy = abs (a[i].y - a[j].y);if (dx + dy == 1) return 0;if (dx <= 2 || dy <= 2) return 1;return 0x3f3f3f3f;
}
void BFS (int s) {memset (dist,0x3f,sizeof (dist));dist[1] = 0;deque <int> q;q.pb (s);while (q.size ()) {int u = q.front ();q.pop_front ();for (int v = 1;v <= k;v++) {if (v == u) continue;int w = get_w (u,v);if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;if (!w) q.pf (v);else q.pb (v);}}}
}
void mian () {cin >> n >> m >> k;int id = -1;for (int i = 1;i <= k;i++) {int x,y;cin >> x >> y;a[i] = {x,y};if (x == n && y == m) id = i;}if (id == -1) a[++k] = {n + 1,m + 1},id = k;BFS (1);// for (int i = 1;i <= k;i++) {// for (int j = 1;j <= k;j++) {// if (get_w (i,j) != 0x3f3f3f3f) cout << i << ' ' << j << ' ' << get_w (i,j) << endl;// }// }if (dist[id] == 0x3f3f3f3f) puts ("-1");else cout << dist[id] << endl;
}
int main () {int T = 1;// cin >> T;while (T--) mian ();return 0;
}