写过二分+bfs的板子题的话,应该能看出来这道也是如此的;
没写过的话;洛谷P1902 刺杀大使。。这是一道二分+bfs的板子题
这道题和板子题的不同之处就在于他有两个变量;
因为二分的对象肯定是海拔的高度差,然后在图中跑找是否存在一条路径中的最高与最低高度差能≤二分的高度差;
那要做到这样的话,相当于能在图中找到这样的路径并找到路径上的最高与最低的高度差;
但很明显如果能有啥算法能做到的话,这道题根本就不需要什么二分+bfs了;
所以只能先二分高度差,然后暴力枚举每一个范围正好的等于高度差的情况。然后跑bfs看看是否存在这样的路径;
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
const int maxn=110;
int n;
int a[maxn][maxn];
bool flag[maxn][maxn];
int dis[4][2]={1,0,0,1,-1,0,0,-1};
bool BFS(int pre,int post)
{
memset(flag,false,sizeof(flag));
queue<P> q;
q.push(P(1,1));
if(a[1][1]<pre||a[1][1]>post) return false;
while(q.size())
{
P p=q.front();
q.pop();
int x=p.first;int y=p.second;
if(x==n&&y==n) return true;
if(flag[x][y]) continue;
flag[x][y]=true;
for(int i=0;i<4;i++)
{
int px=x+dis[i][0],py=y+dis[i][1];
if(px>=1&&px<=n&&py>=1&&py<=n&&flag[px][py]==false&&a[px][py]>=pre&&a[px][py]<=post)
{
q.push(P(px,py));
}
}
}
return false;
}
int main()
{
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];
int l=0,r=110,ans;
while(l<=r)
{
int mid=l+r>>1;
bool prime=false;
for(int i=mid;i<=maxn;i++)
{
if(BFS(i-mid,i))
{
prime=true;
ans=mid;
r=mid-1;
break;
}
}
if(prime==false) l=mid+1;
}
cout<<ans<<endl;
return 0;
}