经典01bfs,用deque维护。
注意几个细节:每个格子会产生4条边 ,最多250000*4数组要开够。
虽然每个点会进很多次,但我们让0的边权放前面,1的边权放后面,每次从双端队列前面取点。
则访问带每个点时,一定是最短路径,即每个点至多执行一次。复杂度是On级别的。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 6e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y,int z)
{
ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt,ee[cnt].val=z;
ee[++cnt].nxt=head[y],ee[cnt].to=x,head[y]=cnt,ee[cnt].val=z;
}
char s[550][550];
int r,c;
int gt(int x,int y)
{
return (x-1)*(c+1)+y;
}
struct node{
int u,z;
};
int vs[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//freopen("1.in","r",stdin);
int t;
cin>>t;
while(t--)
{
init();
cin>>r>>c;
for(int i=1;i<=r;i++)cin>>(s[i]+1);
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
if(s[i][j]=='/')add(gt(i,j+1),gt(i+1,j),0),add(gt(i,j),gt(i+1,j+1),1);
else add(gt(i,j),gt(i+1,j+1),0),add(gt(i,j+1),gt(i+1,j),1);
}
memset(vs,60,sizeof(vs));
vs[1]=0;
deque<node>q;
q.push_back(node{1,0});
while(q.size())
{
node tp=q.front();q.pop_front();
int u=tp.u,z=tp.z;
// printf("%d %d\n",q.size(),u);
for(int i=head[u];i;i=ee[i].nxt)
{
int v=ee[i].to,w=ee[i].val;
if(z+w<vs[v])
{
if(w==1)q.push_back(node{v,z+w}),vs[v]=z+w;
else q.push_front(node{v,z+w}),vs[v]=z+w;
}
}
}
int ans=vs[gt(r+1,c+1)];
if(ans>=1e6)cout<<"NO SOLUTION"<<endl;
else cout<< ans <<endl;
}
return 0;
}