牛客IOI周赛21-普及组 D.瞎位移群岛(bfs)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客IOI周赛21-普及组 D.瞎位移群岛(bfs)相关的知识,希望对你有一定的参考价值。
由于每一秒牛牛都必定在岛屿上,所以只需要考虑当前这一秒能在哪些岛屿上即可
但是每一秒都去 b f s bfs bfs时间开销太大,考虑优化
对于每一秒,设 x x x岛屿发生了移动
我们发现整个图的变化是非常小的,只有 x x x相邻的岛屿会收到影响
设 y y y和 x x x号岛屿相邻
若 y y y可达而 x x x不可达,我们从 x x x开始 b f s bfs bfs
若 y y y不可达而 x x x可达,我们从 y y y开始 b f s bfs bfs
若两者都可达,无需 b f s bfs bfs
若两者都不可达,无需 b f s bfs bfs
这样就在 O ( T + k ) O(T+k) O(T+k)的时间完成搜索
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1009;
int n,m,k,s,t;
int a[maxn][maxn];
int fx[5] = {0,0,-1,1}, fy[5] = {1,-1,0,0};
typedef pair<int,int>p;
p pos[maxn];
int ok[maxn][maxn],ar[maxn];
void bfs(p now)
{
queue<p>q; q.push( now );
ar[a[now.first][now.second]] = 1;
while( !q.empty() )
{
p u = q.front(); q.pop();
for(int i=0;i<4;i++)
{
int nx = u.first+fx[i], ny = u.second+fy[i];
if( nx<1 || nx>n || ny<1 || ny>m ) continue;
if( !a[nx][ny] || ar[a[nx][ny]] ) continue;
ar[a[nx][ny]] = 1; q.push( p(nx,ny) );
}
}
}
int main()
{
cin >> n >> m >> k >> s >> t;
for(int i=1;i<=k;i++)
{
int x,y; scanf("%d%d",&x,&y);
a[x][y] = i;
pos[i] = p(x,y);
}
bfs( pos[s] );
int T,ans=1e9; cin >> T;
if( ar[t] ) ans = 0;
for(int i=1;i<=T;i++)
{
int x,y; scanf("%d%d",&x,&y ); y--;
int nx = pos[x].first+fx[y], ny = pos[x].second+fy[y];
if( nx<1 || nx>n || ny<1 || ny>m || a[nx][ny] ) continue;
a[nx][ny] = x; a[pos[x].first][pos[x].second] = 0;
pos[x] = p(nx,ny);
if( ar[x] ) bfs( pos[x] );
for(int w=0;w<4;w++)
{
int tx = nx+fx[w], ty = ny+fy[w];
if( tx<1 || tx>n || ty<1 || ty>m || !a[tx][ty] ) continue;
if( !ar[a[tx][ty]] ) continue;
if( x==t ) ans = min( ans,i );
else bfs( pos[x] );
}
if( ar[t] ) ans = min( ans,i );
}
if( ans==1e9 ) ans = -1;
cout << ans;
return 0;
}
以上是关于牛客IOI周赛21-普及组 D.瞎位移群岛(bfs)的主要内容,如果未能解决你的问题,请参考以下文章