CF821D
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;
}