思路:
乍一看这题,没有bfs的头绪
但是,我们想到了spfa
我们可以把地图中的每个点看成方格,这样就有(n+1)*(m+1)个方格
如果两点之间有线联通,那它们之间的边权就是0,否则就为1
然后spfa就可以了
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t, js;
int n, m, ans=1000100;
char a[501][501];
int d[501][501];
int f[1000010][4];
int dx[4]={1, -1, 1, -1};
int dy[4]={-1, 1, 1, -1};
bool check(int x, int y)
{
if(x<0||x>n||y<0||y>m)
return 0;
return 1;
}
void bfs()
{
f[1][1]=0;
f[1][2]=0;
f[1][3]=0;
d[0][0]=0;
int hd=0, tl=1, hd1=0, tl1=1;
while(hd1<tl1)
{
js++;
hd=(hd+1)%1000010;
hd1++;
int xx=f[hd][1], yy=f[hd][2];
if(f[hd][3]>=ans)
continue;
if(xx==n&&yy==m)
{
if(f[hd][3]<ans)
ans=f[hd][3];
continue;
}
for(int i=0; i<4; i++)
{
int x1=xx+dx[i], y1=yy+dy[i];
if(!check(x1, y1))
continue;
if(i==0&&d[x1][y1]>f[hd][3]+(a[xx+1][yy]=='\\'))
{
tl=(tl+1)%1000010;
tl1++;
f[tl][1]=x1;
f[tl][2]=y1;
d[x1][y1]=f[hd][3]+(a[xx+1][yy]=='\\');
if(a[xx+1][yy]=='/')
f[tl][3]=f[hd][3];
else
f[tl][3]=f[hd][3]+1;
}
if(i==1&&d[x1][y1]>f[hd][3]+(a[xx][yy+1]=='\\'))
{
tl=(tl+1)%1000010;
tl1++;
d[x1][y1]=f[hd][3]+(a[xx][yy+1]=='\\');
f[tl][1]=x1;
f[tl][2]=y1;
if(a[xx][yy+1]=='/')
f[tl][3]=f[hd][3];
else
f[tl][3]=f[hd][3]+1;
}
if(i==2&&d[x1][y1]>f[hd][3]+(a[xx+1][yy+1]=='/'))
{
tl=(tl+1)%1000010;
tl1++;
d[x1][y1]=f[hd][3]+(a[xx+1][yy+1]=='/');
f[tl][1]=x1;
f[tl][2]=y1;
if(a[xx+1][yy+1]=='\\')
f[tl][3]=f[hd][3];
else
f[tl][3]=f[hd][3]+1;
}
if(i==3&&d[x1][y1]>f[hd][3]+(a[xx][yy]=='/'))
{
tl=(tl+1)%1000010;
tl1++;
d[x1][y1]=f[hd][3]+(a[xx][yy]=='/');
f[tl][1]=x1;
f[tl][2]=y1;
if(a[xx][yy]=='\\')
f[tl][3]=f[hd][3];
else
f[tl][3]=f[hd][3]+1;
}
}
}
}
int main()
{
scanf("%d", &t);
while(t--)
{
memset(d, 1, sizeof(d));
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
a[i][j]=getchar();
while(a[i][j]!='/'&&a[i][j]!='\\')
a[i][j]=getchar();
}
bfs();
if(ans==1000100)
printf("NO SOLUTION\n");
else
printf("%d\n", ans);
js=0;
ans=1000100;
}
return 0;
}