luoguP7284 [COCI 2020/2021 #4] Patkice II
思路
这题怎么敢评绿啊qwq
我们考虑目前的位置是 \((i, j)\),那么如果要去原洋流指向方向不需要改变字符,否则需要。题目要求的是最少改变字符的数量,很明显最短路。
题目转化为:每个位置 \((i, j)\) 连边向上下左右四个方向,如果是原洋流指向方向边权就是 \(0\),否则就是 \(1\),然后求出初始位置到结束位置的最短路长度。最后我们还需要求出改变之后的图,可以发现会改变的只会是最短路径上面的,那么记录 \(pre_{i, j}\) 表示 \((i, j)\) 由那个位置转移过来的即可,然后从结束位置反推回去把方向按 \(pre\) 数组改了即可。
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 2e3 + 3;
const int INF = 1e9;
struct Node {
int x, y, d;
bool operator < (const Node &i) const {
return d > i.d;
}
} ;
int n, m, dist[N][N];
pii pre[N][N];
char c[N][N];
priority_queue<Node> pq;
void Push(int x, int y, int t, int k, int xx, int yy) {
if (!(x > n || x < 1 || y > m || y < 1)) {
if (dist[x][y] > k + t) {
dist[x][y] = k + t;
pre[x][y] = {xx, yy};
pq.push({x, y, k + t});
}
}
}
void Dijkstra() { // Dijkstra 或者 BFS 都可以
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dist[i][j] = INF;
if (c[i][j] == 'o') {
pq.push({i, j, -1});
dist[i][j] = -1;
}
}
}
while (!pq.empty()) {
int x = pq.top().x, y = pq.top().y, d = pq.top().d;
pq.pop();
if (dist[x][y] != d) continue ;
if (c[x][y] == 'x') return ;
int xx = c[x][y] == '^' ? -1 : c[x][y] == 'v' ? 1 : 0, yy = c[x][y] == '<' ? -1 : c[x][y] == '>' ? 1 : 0;
xx += x, yy += y;
Push(xx, yy, 0, dist[x][y], x, y), Push(x + 1, y, 1, dist[x][y], x, y), Push(x - 1, y, 1, dist[x][y], x, y), Push(x, y + 1, 1, dist[x][y], x, y), Push(x, y - 1, 1, dist[x][y], x, y);
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> c[i][j];
}
}
Dijkstra();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (c[i][j] == 'x') {
cout << dist[i][j] << "\n";
for (int k = i, l = j; c[pre[k][l].first][pre[k][l].second] != 'o'; ) {
int x = pre[k][l].first, y = pre[k][l].second;
c[x][y] = x - k == 1 ? '^' : x - k == -1 ? 'v' : y - l == 1 ? '<' : '>';
k = x, l = y;
}
for (int k = 1; k <= n; k++) {
for (int l = 1; l <= m; l++) {
cout << c[k][l];
}
cout << "\n";
}
}
}
}
return 0;
}
// 你想知道藏海花的故事吗……

浙公网安备 33010602011771号