E-小红走矩阵_牛客周赛 Round 51 (nowcoder.com)
方法1 dijkstr
用最短路来做,可以用堆优化版本的dijkstr来做.不过这里并不是求最短路,而是求最小路径权值
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=505;
int a[N][N];
int dist[N][N];
bool vis[N][N];
int dx[4]={0,1,0,-1},dy[4]={-1,0,1,0};
int n;
struct node
{
int x,y,st;
bool operator<(const node& b)const
{
return st>b.st;
}
};
priority_queue<node>q;
void bfs()
{
q.push({ 1,1,a[1][1] });
memset(dist,0x3f,sizeof dist);
dist[1][1] = a[1][1];
while(!q.empty())
{
node t=q.top();
q.pop();
for(int i=0;i<4;i++)
{
int tx=t.x+dx[i];
int ty=t.y+dy[i];
if(tx<1||tx>n||ty<1||ty>n||vis[tx][ty])continue;
dist[tx][ty]=max(a[tx][ty],dist[t.x][t.y]);
q.push({tx,ty,dist[tx][ty]});
vis[tx][ty]=true;
}
}
}
signed main(void)
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)cin>>a[i][j];
bfs();
cout << dist[n][n];
return 0;
}
方法2 bfs+2分
#include<bits/stdc++.h>
using namespace std;
const int N = 505;
int dirs[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int n;
int a[N][N];
bool vis[N][N];
bool check(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= n;
}
bool bfs(int mid) {
if (a[1][1] > mid) return 0;
memset(vis, 0, sizeof(vis));
queue<pair<int, int>> q;
q.push({1, 1});
vis[1][1] = 1;
while (!q.empty()) {
auto [x, y] = q.front(); q.pop();
// cerr << x << " " << y << '\n';
if (x == n && y == n) return 1;
for (int i = 0; i < 4; ++i) {
int dx = x + dirs[i][0];
int dy = y + dirs[i][1];
if (check(dx, dy) && !vis[dx][dy] && a[dx][dy] <= mid) {
vis[dx][dy] = 1;
q.push({dx, dy});
}
}
}
return 0;
}
int check2() {
int l = a[1][1], r = 1e9, ans = 1e9;
while (l <= r) {
int mid = l + (r - l) / 2;
if (bfs(mid)) {
ans = mid;
r = mid - 1;
//l = mid + 1;
} else {
l = mid + 1;
//r = mid - 1;
}
}
return ans;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cin >> a[i][j];
}
}
cout << check2();
return 0;
}