/* ID: espr1t TASK: KEYWORDS: */ #include #include #include #include #include #include using namespace std; FILE *in; FILE *out; const int MM = 9; const int MAX = 204; const int MASK = (1 << MM); const int INF = 1000000001; struct State { int row, col, price; State(int row_ = -1, int col_ = -1, int price_ = -1) : row(row_), col(col_), price(price_) {} bool operator < (const State& r) const { return price > r.price; } }; int n, k; int a[MM][2]; int h[MAX][MAX]; bool vis[MAX][MAX]; int dist[MM][MAX][MAX]; int dir[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} }; int getPrice(int h1, int h2) { return 1 + (h1 >= h2 ? (h1 - h2) : (h1 - h2) * (h1 - h2)); } void findDist(int node) { memset(vis, 0, sizeof(vis)); memset(dist[node], 63, sizeof(int) * MAX * MAX); dist[node][a[node][0]][a[node][1]] = 0; priority_queue q; q.push(State(a[node][0], a[node][1], 0)); while (!q.empty()) { int row = q.top().row, col = q.top().col, price = q.top().price; q.pop(); if (vis[row][col]) continue; vis[row][col] = true; dist[node][row][col] = price; for (int i = 0; i < 4; i++) { int nrow = row + dir[i][0]; if (nrow < 0 || nrow >= n) continue; int ncol = col + dir[i][1]; if (ncol < 0 || ncol >= n) continue; int nprice = price + getPrice(h[row][col], h[nrow][ncol]); if (dist[node][nrow][ncol] > nprice) { dist[node][nrow][ncol] = nprice; q.push(State(nrow, ncol, nprice)); } } } } int dyn[MM][MASK]; int recurse(int node, int mask) { if (mask == (1 << k) - 1) return 0; if (dyn[node][mask] != -1) return dyn[node][mask]; int ans = INF; for (int i = 1; i < k; i++) if (!(mask & (1 << i))) { ans = min(ans, recurse(i, mask | (1 << i)) + dist[node][a[i][0]][a[i][1]]); } return dyn[node][mask] = ans; } int solve() { for (int i = 0; i < k; i++) findDist(i); memset(dyn, -1, sizeof(dyn)); return recurse(0, (1 << 0)); } int main(void) { in = stdin; out = stdout; in = fopen("invaders.in", "rt"); out = fopen("invaders.out", "wt"); fscanf(in, "%d %d", &n, &k); for (int i = 0; i < n; i++) for (int c = 0; c < n; c++) fscanf(in, "%d", &h[i][c]); k++; for (int i = 0; i < k; i++) { fscanf(in, "%d %d", &a[i][0], &a[i][1]); a[i][0]--, a[i][1]--; } fprintf(out, "%d\n", solve()); return 0; }