大意給一個圖,讓你從左頂點走到右下角,且路徑上最大的權值與最小的權值之差最小。
5 1 1 3 6 8 1 2 2 5 5 4 4 0 3 3 8 0 2 3 4 4 3 0 2 1
輸出 2.
剛開始就想着暴搜能過幾個樣例。結果T的我懷疑人生,題目正解是個二分加暴搜,感覺時間複雜度也不低,但是過了。。。。
找出最大權值與最小權值,通過二分兩者差值來找最優解,又理解了一下上次學習的二分算法,對圖的遍歷又有了一種新的體會
#include <iostream>
#include <cstring>
using namespace std;
int map[110][110],vis[110][110],n,mmax,cun[4][2]={{0,1},{0,-1},{1,0},{-1,0}},low,up;
int dfs(int x,int y)
{ vis[x][y]=1;
if(x==n-1&&y==n-1)
{
return 1;
}
for(int i=0;i<4;i++)
{
int xx=x+cun[i][0];
int yy=y+cun[i][1];
if(xx>=0&&xx<n&&map[xx][yy]>=low&&map[xx][yy]<=up&&yy>=0&&yy<n&&!vis[xx][yy])
{
if(dfs(xx,yy))
return 1;
}
}
return 0;
}
bool judge(int tt)
{ int ss=map[0][0]
for(int i=0;i+tt<=111;i++)
{ memset(vis,0,sizeof(vis));
vis[0][0]=1;
up=i+tt;
low=i;
if(dfs(0,0))
return 1;
}
return 0;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&map[i][j]);
int l=0,r=110;
while(l<r)
{
int mod=(l+r)/2;
if(judge(mod)) r=mod;
else
l=mod+1;
}
cout<<l<<endl;
return 0;
}