P2658 汽车拉力比赛

题目描述
思路:
其实这一题说难不难,说简单也并不简单。关键是先用二分求期望值,再将期望值用 b f s bfs bfs进行判断。
特别要注意的是,在 b f s bfs bfs时,要注意判断路标的个数。

代码:

#include 
#pragma GCC optimize(2)
using namespace std;

template < typename T > void read(T &x)
{
	int f = 1;x = 0;char c = getchar();
	for (;!isdigit(c);c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c);c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

int n, m, a[505][505];
bool b[505][505];
bool vis[505][505];
int dx[5] = {0, 0, 1, 0, -1};
int dy[5] = {0, 1, 0, -1, 0};

struct node
{
	int x, y;
};

int need = 0;

void input()
{
	read(n);
	read(m);
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= m;j++)
			read(a[i][j]);
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= m;j++)
		{
			cin >> b[i][j];
			if(b[i][j]) need++;
		}	
}

bool check(int mid)
{
	int key;
	node fx;
	fx.x = 1;
	fx.y = 1;
	vis[1][1] = 1;
	if(b[1][1] == true)  
		key = 1;
	else key = 0;
	queue < node > q;
	q.push(fx);
	while(!q.empty())
	{
		node temp = q.front();
		q.pop();
		for(int i = 1;i <= 4;i++)
		{
			int tx = temp.x + dx[i];
			int ty = temp.y + dy[i];
			if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && abs(a[tx][ty] - a[temp.x][temp.y]) <= mid && vis[tx][ty] == 0)
			{
				if(b[tx][ty] == true) key++;
				node qp;
				qp.x = tx;
				qp.y = ty;
				q.push(qp);
				vis[tx][ty] = 1;
				if(key == need) return true;
			}
		}
	}
	return false;
}

int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	input();
	int l = 0, r = 1e9, ans;
	if(need == 1)
	{
		cout << 0 << endl;
		return 0;
	}
	while(l <= r)
	{	
		memset(vis, 0, sizeof(vis));
		int mid = (l + r) / 2;
		bool flag = check(mid);
		if(flag) 
		{
			ans = mid;
			r = mid - 1;
		}
		else l = mid + 1;
	}
	cout << ans << endl;
	return 0;
}

你可能感兴趣的:(P2658 汽车拉力比赛)