P2658 汽车拉力比赛

题目描述

博艾市将要举行一场汽车拉力比赛。

赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间。

其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D。也就是说这个难度系数D指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。

输入格式

第一行两个整数M和N。第2行到第M+1行,每行N个整数描述海拔高度。第2+M行到第1+2M

行,每行N个整数,每个数非0即1,1表示该单元格是一个路标。

输出格式

一个整数,即赛道的难度系数D。

输入输出样例

输入 #1
3 5 
20 21 18 99 5  
19 22 20 16 26
18 17 40 60 80
1 0 0 0 1
0 0 0 0 0
0 0 0 0 1
输出 #1
21


乍一看我还以为是一道最短路,后来发现好像是BFS(貌似有人用了并查集)


二分答案+BFS;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define maxn 5555
using namespace std;

int n,m,maze[maxn][maxn],cnt,kk[maxn][maxn],startx,starty;

bool vis[maxn][maxn];

struct node{
    int x,y;
}a[maxn][maxn];

const int dx[4]={1,-1,0,0};

const int dy[4]={0,0,1,-1};

int abss(int a,int b){
    if(a>b) return a-b;
    else return b-a;
}

bool check(int s)
{
    queue<node> q;
    memset(vis,false,sizeof(vis));
    vis[startx][starty]=true;
    q.push(a[startx][starty]);
    int sum=1;
    while(!q.empty())
    {
        node cur=q.front();
        q.pop();
        for(int k=0;k<4;k++)
        {
            int x1=cur.x+dx[k];
            int y1=cur.y+dy[k];
            if(x1<1||x1>m||y1<1||y1>n||vis[x1][y1]||abss(maze[x1][y1],maze[cur.x][cur.y])>s){
                continue;
            }
            vis[x1][y1]=true;
            sum+=kk[x1][y1];
            q.push(a[x1][y1]);
            if(sum==cnt){
                return true;
            }

        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&m,&n);
    int low=0,high=0,mid,ans;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&maze[i][j]);
            a[i][j].x=i;
            a[i][j].y=j;
            high=max(high,maze[i][j]);
        }
    }
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&kk[i][j]);
            if(kk[i][j])
            {
                cnt++;
                if(cnt==1)
                {
                    startx=i;
                    starty=j;
                }
            }
        }
    }
    while(low<=high)
    {
        mid=(low+high)/2;
        if(check(mid)){
            ans=mid;
            high=mid-1;
        }
        else low=mid+1;
    }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hrj1/p/11723616.html
今日推荐