洛谷2658 汽車拉力比賽ios
本題地址: http://www.luogu.org/problem/show?pid=2658ide
題目描述spa
博艾市將要舉行一場汽車拉力比賽。
賽場凹凸不平,因此被描述爲M*N的網格來表示海拔高度(1≤ M,N ≤500),每一個單元格的海拔範圍在0到10^9之間。
其中一些單元格被定義爲路標。組織者但願給整個路線指定一個難度係數D,這樣參賽選手從任一路標到達別的路標所通過的路徑上相鄰單元格的海拔高度差不會大於D。也就是說這個難度係數D指的是保證全部路標相互可達的最小值。任一單元格和其東西南北四個方向上的單元格都是相鄰的。code
輸入輸出格式blog
輸入格式:ci
第一行兩個整數M和N。第2行到第M+1行,每行N個整數描述海拔高度。第2+M行到第1+2M
行,每行N個整數,每一個數非0即1,1表示該單元格是一個路標。get
輸出格式:string
一個整數,即賽道的難度係數D。it
輸入輸出樣例io
輸入樣例#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。
二分D,BFS判斷是否能夠到達所有路標便可。
【代碼】
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cmath> 5 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 6 using namespace std; 7 8 const int maxn = 500+10; 9 const int INF=1e9; 10 const int dx[]={0,0,1,-1}; 11 const int dy[]={1,-1,0,0}; 12 struct Node{ 13 int x,y; 14 }; 15 int is_P[maxn][maxn]; 16 int G[maxn][maxn]; 17 int n,m,sx,sy,sum=0; 18 bool inside(int x,int y) { 19 return x>0 && x<=n && y>0 && y<=m; 20 } 21 bool can(int D) { 22 queue<Node> q; 23 bool vis[maxn][maxn]; 24 memset(vis,0,sizeof(vis)); 25 26 int cnt=1; 27 vis[sx][sy]=1; 28 q.push((Node){sx,sy}); 29 while(!q.empty()) { 30 Node u=q.front(); q.pop(); 31 int x=u.x,y=u.y; 32 FOR(i,0,3) { 33 int xx=x+dx[i],yy=y+dy[i]; 34 if(inside(xx,yy) && !vis[xx][yy] &&(abs(G[xx][yy]-G[x][y])<=D)) { 35 vis[xx][yy]=1; 36 cnt += is_P[xx][yy]; 37 if(cnt==sum) return true; 38 q.push((Node){xx,yy}); 39 } 40 } 41 } 42 return false; 43 } 44 45 int main() { 46 ios::sync_with_stdio(false); 47 cin>>n>>m; 48 int _min=INF,_max=0; 49 FOR(i,1,n) FOR(j,1,m){ 50 cin>>G[i][j]; 51 _min=min(_min,G[i][j]); 52 _max=max(_max,G[i][j]); 53 } 54 FOR(i,1,n) FOR(j,1,m) { 55 cin>>is_P[i][j]; 56 sum += is_P[i][j]; 57 if(is_P[i][j]) sx=i,sy=j; //從1開始 58 } 59 int L=0,R=_max-_min+1; 60 while(L<R) { 61 int M=L+(R-L)/2; 62 if(can(M)) R=M; 63 else L=M+1; 64 } 65 cout<<L<<"\n"; 66 return 0; 67 }