这道题的解法非常妙。
一开始,我的想法是:在bfs是搜索过程中带着状态变量con(表示是否遇到过墨菲斯托或莉莉丝,两个都遇到了这个路线就不成立,可以pop掉。)但是发现这样vis数组会其冲突,压缩起来会比较麻烦。
参考大佬的解法:分两次bfs
第一次,将墨菲斯托的位置全部设为无法进入,莉莉丝设为空房间,bfs一次,得出最短路。这一步的目的是:求出不经过墨菲斯托所在位置能不能得到书,能的话,返回最短距离,不能则返回-1。
第二次反过来,墨菲斯托设为空房间,莉莉丝设为无法进入,再进行一次bfs。同样的,这一步的求出不经过莉莉丝能不能得到书。
然后,综合两次结果得出结论:
若两个结果都是-1,说明不管怎么走,都会遇到墨菲斯托,并且都会遇到莉莉丝,因此,IMPOSSIBLE
若只有其中一个不是-1,说明一个是一定要遇到的,另一个可以不遇到,那就输出不为-1的那一个。
否则,两个都不是-1,都可以不遇到,那当然取min的那个。
为什么这道题可以这么做呢?因为两个人中一定需要有一个遇不到才存在可行方案,所以,我们可以分两次bfs,得出是否存在方案可以避开两人中的一人,来判断是不是IMPOSSIBLE。
#include <iostream> #include <map> #include <ctime> #include <vector> #include <climits> #include <algorithm> #include <random> #include <cstring> #include <cstdio> #include <map> #include <set> #include <bitset> #include <queue> #define inf 0x3f3f3f3f #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #define rep(i, a, n) for(register int i = a; i <= n; ++ i) #define per(i, a, n) for(register int i = n; i >= a; -- i) //#define ONLINE_JUDGE using namespace std; typedef long long ll; const int mod=1e9+7; template<typename T>void write(T x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar(x%10+'0'); } template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;}; ll ksm(ll a,ll n){//看是否要mod ll ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans%mod; } //============================================================== const int maxn=1e3+10; int t,n,m,r,c; struct node{ int x,y,step; node(int xx,int yy,int sp){ x=xx,y=yy,step=sp; } }; char a[maxn][maxn]; char mp[maxn][maxn]; int vis[maxn][maxn]={0}; int dir[4][2]={1,0,-1,0,0,1,0,-1}; int bfs(){ memset(vis,0,sizeof(vis)); queue<node> que; que.push(node(1,1,0)); vis[1][1]=1; while(!que.empty()){ node a=que.front(); que.pop(); if(a.x==r&&a.y==c){ return 2*a.step; } rep(i,0,3){ int dx=a.x+dir[i][0],dy=a.y+dir[i][1]; if(vis[dx][dy]||dx<=0||dy<=0||dx>n||dy>m||mp[dx][dy]=='*') continue; vis[dx][dy]=1; node tmp(dx,dy,a.step+1); que.push(tmp); } } return -1; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif //=========================================================== read(t); while(t--){ memset(vis,0,sizeof(vis)); read(n),read(m),read(r),read(c); rep(i,1,n){ rep(j,1,m){ cin>>a[i][j]; } } rep(i,1,n){ rep(j,1,m){ if(a[i][j]=='M'){ mp[i][j]='*'; } else if(a[i][j]=='F'){ mp[i][j]='.'; } else mp[i][j]=a[i][j]; } } int ans1=bfs(); rep(i,1,n){ rep(j,1,m){ if(a[i][j]=='F'){ mp[i][j]='*'; } else if(a[i][j]=='M'){ mp[i][j]='.'; } else{ mp[i][j]=a[i][j]; } } } int ans2=bfs(); if(ans1==-1&&ans2==-1){ puts("IMPOSSIBLE"); } else if(ans1==-1||ans2==-1){ write(max(ans1,ans2)),putchar('\n'); } else{ write(min(ans1,ans2)),putchar('\n'); } } //=========================================================== return 0; }