经典二分求解题面:使最大值最小化。
阅读本题后可发现,仅需找到一条从第一行走到最后一行且中途经过的所有点权中最大值的最小值即为所求,因为其它派遣的士兵都可通过这条路到达最后一行后再进行转移,且不会改变先前的答案。
而由于第一行和最后一行内部都是无需消耗的互通,因此可直接令起点为 ( 1 , 1 ) (1,1) (1,1) 终点为 ( n , 1 ) (n,1) (n,1) 。同时二分答案,注意处理 b f s bfs bfs 中的边界问题。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1010;
int n,m;
int g[N][N];
bool vis[1001][1001];
void bfs(int x,int y,int mid){
if(x<1||y<1||x>n||y>m||vis[x][y]||g[x][y]>mid)
return;
vis[x][y]=1;
bfs(x+1,y,mid);
bfs(x,y+1,mid);
bfs(x-1,y,mid);
bfs(x,y-1,mid);
}
bool check(int mid){
memset(vis,0,sizeof vis);
bfs(1,1,mid);
return vis[n][1];
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>g[i][j];
int l=1,r=1000;
while(l<r){
int mid=(l+r)>>1;
if(check(mid))
r=mid;
else
l=mid+1;
}
cout<<l;
return 0;
}