【BZOJ】3432: [Usaco2014 Jan]Cross Country Skiing (bfs+二分)

http://www.lydsy.com/JudgeOnline/problem.php?id=3432

题目说要相互可达,但是只需要从某个点做bfs然后判断其它点是否可达即可。

原因太简单了。。。。。因为它是abs

所以我们二分D,然后判断即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr2(a, b, c) for1(i, 1, b) { for1(j, 1, c) cout << a[i][j]; cout << endl; }
#define printarr1(a, b) for1(i, 1, b) cout << a[i]; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=505, M=300005, dx[]={-1, 1, 0, 0}, dy[]={0, 0, 1, -1};
int mp[N][N], must[N][N], n, m, front, tail, vis[N][N], X, Y;
struct dat{ int x, y; }q[M];

void bfs(int D) {
	for1(i, 1, n) for1(j, 1, m) vis[i][j]=0;
	front=tail=0;
	q[tail].x=X, q[tail++].y=Y; vis[X][Y]=1;
	int x, y;
	while(tail!=front) {
		dat &t=q[front++]; if(front==M) front=0;
		x=t.x, y=t.y;
		rep(i, 4) {
			int fx=dx[i]+x, fy=dy[i]+y;
			if(fx<1 || fy<1 || fx>n || fy>m || vis[fx][fy] || abs(mp[fx][fy]-mp[x][y])>D) continue;
			vis[fx][fy]=1;
			q[tail].x=fx; q[tail++].y=fy; if(tail==M) tail=0;
		}
	}
}
bool check(int D) {
	bfs(D);
	for1(i, 1, n) for1(j, 1, m) if(must[i][j]==1 && !vis[i][j]) return false;
	return true;
}

int main() {
	int mx=0;
	read(n); read(m);
	for1(i, 1, n) for1(j, 1, m) read(mp[i][j]), mx=max(mx, mp[i][j]);
	for1(i, 1, n) for1(j, 1, m) {
		read(must[i][j]); if(must[i][j]==1) X=i, Y=j;
	}
	int l=0, r=mx;
	while(l<=r) {
		int mid=(l+r)>>1;
		if(check(mid)) r=mid-1;
		else l=mid+1;
	}
	print(r+1);
	return 0;
}

 

 


 

 

Description

 The cross-country skiing course at the winter Moolympics is described by an M x N grid of elevations (1 <= M,N <= 500), each elevation being in the range 0 .. 1,000,000,000. Some of the cells in this grid are designated as waypoints for the course. The organizers of the Moolympics want to assign a difficulty rating D to the entire course so that a cow can reach any waypoint from any other waypoint by repeatedly skiing from a cell to an adjacent cell with absolute elevation difference at most D. Two cells are adjacent if one is directly north, south, east, or west of the other. The difficulty rating of the course is the minimum value of D such that all waypoints are mutually reachable in this fashion.

N*M的格子,每个格子都有一个分值v,有的格子一定要经过.两个格子i,j可以互相到达,当且仅当它们有一条边重复(即上下左右方向),且abs(vi-vj)<=D.

Input

* Line 1: The integers M and N.

* Lines 2..1+M: Each of these M lines contains N integer elevations.

* Lines 2+M..1+2M: Each of these M lines contains N values that are either 0 or 1, with 1 indicating a cell that is a waypoint.

Output

* Line 1: The difficulty rating for the course (the minimum value of D such that all waypoints are still reachable from each-other).

Sample Input

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

INPUT DETAILS: The ski course is described by a 3 x 5 grid of elevations. The upper-left, upper-right, and lower-right cells are designated as waypoints.

Sample Output

21

OUTPUT DETAILS: If D = 21, the three waypoints are reachable from each-other. If D < 21, then the upper-right waypoint cannot be reached from the other two.

HINT

Source

转载于:https://www.cnblogs.com/iwtwiioi/p/3981920.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值