E:
有三种解法
dfs+二分
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
#define pii pair<int,int>
const int N=510;
bool st[N][N];
int g[N][N];
int n;
int res;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
// bool check(int x,int y)
// {
// return x>0&&y>0&&x<=n&&y<=n;
// }
void dfs(int mid,int x,int y,int cnt)
{
st[x][y]=true;
if(x==n&&y==n)
{
res=min(res,cnt);
return ;
}
//if(cnt>res)return;
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx<=0||tx>n||ty<=0||ty>n)continue;
if(g[tx][ty]>mid)continue;
if(st[tx][ty])continue;
cnt=max(cnt,g[tx][ty]);
dfs(mid,tx,ty,cnt);
}
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>g[i][j];
int l=0,r=1e9+1;
while(l<r)
{
memset(st,0,sizeof st);
int mid=l+r>>1;
res=1e9+10;
dfs(mid,1,1,g[1][1]);
if(res<=mid)r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}
bfs+二分
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
#define pii pair<int,int>
const int N=510;
bool st[N][N];
int g[N][N];
int n;
int res;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
bool check(int x,int y)
{
return x>0&&y>0&&x<=n&&y<=n;
}
bool bfs(int mid)
{
if(g[1][1]>mid)return false;//起点值可能大于mid
queue<pii> q;
q.push({1,1});
st[1][1]=true;
while(q.size())
{
auto [x,y]=q.front();q.pop();
if(x==n&&y==n)return true;
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(check(tx,ty)&&g[tx][ty]<=mid&&!st[tx][ty])
{
st[tx][ty]=true;
q.push({tx,ty});
}
}
}
return false;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>g[i][j];
int l=0,r=1e9+10;
while(l<r)
{
memset(st,0,sizeof st);
int mid=l+r>>1;
//res=1e9+10;
if(bfs(mid))r=mid;
else l=mid+1;
}
cout<<r<<endl;
return 0;
}
dijsktra
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef pair<int,int> pii;
typedef pair<pii,int> piii;
#define x first
#define y second
int n,m;
int dist[N][N];//存每个点到起点的距离
int a[N][N];
bool st[N][N];
int dx[]={0,0,-1,1},dy[]={1,-1,0,0};
int dijsktra()
{
dist[1][1]=a[1][1];
priority_queue<piii,vector<piii>,greater<piii> > q;
//堆会按第一个值的大小排序
q.push({{a[1][1],1},1});
while(q.size())
{
auto t=q.top();q.pop();
int x=t.x.y,y=t.y;
if(st[x][y])continue;
st[x][y]=true;//将当前点加入st
for(int k=0;k<4;k++)
{//遍历每个点可以到的点
int tx=x+dx[k],ty=y+dy[k];
if(tx<=0||tx>n||ty>n||ty<=0)continue;
//更新最短路径
if(max(dist[x][y],a[tx][ty])<dist[tx][ty])
{
dist[tx][ty] = max(dist[x][y], a[tx][ty]);
q.push({{dist[tx][ty],tx},ty});
}
}
}
return dist[n][n];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dist[i][j]=1e9+10;//一开始都为无穷大
cout<<dijsktra();
return 0;
}