不难发现如果一个边的方向改变,就一定不会改回来(这样肯定不是最短路).
所以就直接建双向边,边权为 $0$ 代表不改变,边权为 $1$ 代表改变,跑一个最短路即可.
#include <bits/stdc++.h>
#define N 600
#define M 1000000
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
char str[N];
int id[N][N],tot,edges,s;
int hd[M],to[M],nex[M],val[M],done[M],d[M];
void addedge(int u,int v,int c)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
swap(u,v);
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
struct P
{
int u,dis;
P(int u=0,int dis=0):u(u),dis(dis){}
bool operator<(P b) const
{
return b.dis<dis;
}
};
priority_queue<P>q;
void Dijkstra()
{
for(int i=0;i<M;++i) d[i]=inf;
for(d[s]=0,q.push(P(s,0));!q.empty();)
{
P e=q.top();
q.pop();
int u=e.u;
if(done[u]) continue;
done[u]=1;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(d[v]>d[u]+val[i])
{
d[v]=d[u]+val[i];
q.push(P(v,d[v]));
}
}
}
}
int main()
{
// setIO("input");
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n+1;++i)
for(j=1;j<=m+1;++j) id[i][j]=++tot;
for(i=1;i<=n;++i)
{
scanf("%s",str+1);
for(j=1;j<=m;++j)
{
if(str[j]=='/')
{
addedge(id[i+1][j],id[i][j+1],0);
addedge(id[i][j],id[i+1][j+1],1);
}
else
{
addedge(id[i][j],id[i+1][j+1],0);
addedge(id[i+1][j],id[i][j+1],1);
}
}
}
s=id[1][1];
int t=id[n+1][m+1];
Dijkstra();
if(d[t]==inf) printf("NO SOLUTION\n");
else printf("%d\n",d[t]);
return 0;
}