一道比较有思维难度的广搜题。

每一个时刻会有一个岛屿发生移动,求最快多长时间能到目标点,很容易想到广搜。

首先将起点BFS一次,标记出所有能到的点,如果此时已经能到目标点了,直接输出0就行了。

然后对于每一个时刻,有一个岛移动了,考虑这个移动有哪些情况。

1.移动的这个岛恰好是之间标记过的岛,也就是可以从这个岛出发,这次移动之后,要把这个点BFS一遍。把能到达的岛标记出来。

2.移动的这个岛是之前没标记过的岛,也就是即使可以从这个岛出发走到终点,现在也没法走,因为之前没有上过这个岛。
所以只有这个岛和之前标记过的岛连到一起才可能拓展出更多的岛,也就是把这个点BFS一遍,只有存在恰好有跟它相邻且标记过的岛才能满足继续拓展的条件。

#include<bits/stdc++.h>
using namespace std;
int n,m,k,s,t;
int mp[1010][1010];//a[i][j]表示(i,j)上的岛屿的标号,没有就是0
int x[1010],y[1010];
int vis[1010];//标记到达过的岛屿 
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
void dfs(int x0,int y0)//拓展
{
    vis[mp[x0][y0]]=1;
    for(int i=0;i<4;i++)
    {
        int xx=x0+dx[i];
        int yy=y0+dy[i];
        if(xx<=0||xx>n||yy<0||yy>m||vis[mp[xx][yy]]||mp[xx][yy]==0)//不能走到没岛屿的地方或者重复走 
        continue;
        dfs(xx,yy);
    }
} 
int main()
{
    cin>>n>>m>>k>>s>>t;
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        mp[x[i]][y[i]]=i; 
    }
    int T;
    cin>>T;
    int tot=0;
    dfs(x[s],y[s]);
    if(vis[t])
    {
        cout<<"0";
        return 0;
    } 
    while(T--)
    {
        int a,b,xx,yy;
        scanf("%d%d",&a,&b);
        if(b==1)
        {
            xx=x[a];
            yy=y[a]+1;
        }
        if(b==2)
        {
            xx=x[a];
            yy=y[a]-1;
        }
        if(b==3)
        {
            xx=x[a]-1;
            yy=y[a];
        }
        if(b==4)
        {
            xx=x[a]+1;
            yy=y[a];
        }
        if(mp[xx][yy]||xx<=0||xx>n||yy<=0||yy>m)//注意不能撞到岛屿 
        {
            tot++;
            continue;
        }
        mp[x[a]][y[a]]=0;
        x[a]=xx;
        y[a]=yy;
        mp[x[a]][y[a]]=a;
        if(vis[a])//移动了一个之前可经过的 
        dfs(x[a],y[a]);
        else
        {
            for(int i=0;i<4;i++)
            {
                int tx=xx+dx[i];
                int ty=yy+dy[i];
                if(vis[mp[tx][ty]])
                {
                    dfs(tx,ty);
                }
            } 
        }
        tot++;
        if(vis[t])
        {
            cout<<tot<<endl;
            return 0;
        }
    }
    cout<<"-1";
    return 0;
}