牛客周赛 Round 51 E-小红走矩阵 题型:dijkstr bfs+二分

88 阅读1分钟

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

image.png

方法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;
}

image.png