牛客周赛51 E:三种解法

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值