洛谷—— P2658 汽车拉力比赛

https://www.luogu.org/problem/show?pid=2658

题目描述

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

赛场凹凸不平,所以被描述为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验证是否可以遍历全部路标
 1 #include <cstring>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <queue>
 5 
 6 #define max(a,b) (a>b?a:b)
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>'9'||ch<'0'; ) ch=getchar();
11     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
12 }
13 const int N(555);
14 int n,m,h[N][N],cnt;
15 int go[N][N],sx,sy;
16 
17 bool vis[N][N];
18 int fx[4]={0,1,0,-1};
19 int fy[4]={1,0,-1,0};
20 struct Node {
21     int x,y;
22     int cnt;
23 }u,v;
24 int l,r,mid,ans;
25 inline bool check(int x)
26 {
27     int ret=1;
28     std::queue<Node>que;
29     memset(vis,0,sizeof(vis));
30     u.cnt=1; u.x=sx; u.y=sy;
31     que.push(u); vis[sx][sy]=1;
32     for(; !que.empty(); que.pop())
33     {
34         u=que.front();
35         if(ret==cnt) return 1;
36         for(int i=0; i<4; ++i)
37         {
38             v.x=u.x+fx[i];
39             v.y=u.y+fy[i];
40             if(vis[v.x][v.y]||v.x>n||v.y>m||v.x<1||v.y<1) continue;
41             if(abs(h[u.x][u.y]-h[v.x][v.y])<=x)
42             {
43                 que.push(v),vis[v.x][v.y]=1;
44                 if(go[v.x][v.y]) ret++;
45             }
46         }
47     }
48     return 0;
49 }
50 
51 int Presist()
52 {
53     read(n),read(m);
54     for(int i=1; i<=n; ++i)
55       for(int j=1; j<=m; ++j)
56         read(h[i][j]),r=max(r,h[i][j]);
57     for(int x,i=1; i<=n; ++i)
58       for(int j=1; j<=m; ++j)
59       {
60           read(go[i][j]);
61         if(go[i][j])
62           { cnt++;sx=i;sy=j; }
63       }
64     for(; l<=r; )
65     {
66         mid=l+r>>1;
67         if(check(mid))
68         {
69             ans=mid;
70             r=mid-1;
71         }
72         else l=mid+1;
73     }
74     printf("%d
",ans);
75     return 0;
76 }
77 
78 int Aptal=Presist();
79 int main(int argc,char*argv[]){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7588707.html