solution-p4955
题解 P4955 【[USACO14JAN]Cross Country Skiing S】
乍一看,要求最小的难度值D,于是考虑二分答案 + bfs/dfs。
如果一个关键格\((x,y)\)能够到达关键格\((xi,yi)\)和\((xj , yj)\)
那么\((xi,yi)\)也能通过\((x,y)\)到达\((xj,yj)\),反之亦然。
所以只要验证:
\((x,y)\)是否能够到达所有其他关键格即可。
代码
时间复杂度\(O(NMlog\;a[i][j])\)
// 此处应有头文件
using namespace std;
const int N = 5e2 + 10;
int n,m;
int a[N][N]; // 存地图
bool vis[N][N]; // 是否访问过
int fsum = 0; // 关键格数量
bool f[N][N]; // 是否为关键格
struct node
{
int x,y;
};
int dx[] = {0 , 0 , -1 , 1};
int dy[] = {-1 , 1 , 0 , 0}; // 移动
int sx,sy; // 存其中一个关键格的位置
bool bfs(int k)
{
memset( vis , false , sizeof(vis) );
queue<node> q;
q.push( (node){sx , sy} );
vis[sx][sy] = true;
int sum = 0; // 已经访问到多少个关键格
while( !q.empty() )
{
node t = q.front();
q.pop();
if( f[t.x][t.y] )
++sum;
if(sum >= fsum)
return true;
for(int i = 0;i < 4;i++)
{
int xx = t.x + dx[i];
int yy = t.y + dy[i];
if( xx > 0 && yy > 0 && xx <= n && yy <= m && !vis[xx][yy] )
{
if( abs( a[t.x][t.y] - a[xx][yy] ) <= k )
{
q.push( (node){xx , yy} );
vis[xx][yy] = true;
}
}
}
}
return false;
}
bool check(int k)
{
if( !bfs(k) )
return false;
return true;
}
int main()
{
int l = 0;
int r = 0;
cin >> n >> m;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
{
cin >> a[i][j];
r = max(a[i][j] , r); // 取全地图的最高点作为右界限
}
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
{
cin >> f[i][j];
if( f[i][j] )
{
++fsum;
sx = i,sy = j; // 存其中一个关键格的位置
}
}
while(l < r) // 二分答案
{
int mid = l + r >> 1; // 右移一位 = /2
if( check(mid) )
r = mid;
else
l = mid + 1;
}
cout << l << endl;
return 0;
}

浙公网安备 33010602011771号