看了眼题解,貌似没有和我的思路一样的…
所以就来写一篇题解…
首先我不会什么双向BFS也懒得写最短路…
所以,就一个BFS 闯遍天下
先看题:
感性理解一下…貌似如(1,2),(2,1),(1,4),(4,1)都到不了 虽然这个么什么用
好了,进入主题
首先,BFS是一个队列,为了保证结果的真确性,所以存当前花费的数组必须符合单调性,不然就没法达到最短路的效果了(开始就是没注意单调,调了2个小时)可以发现一个点可以直接到四个点,而到这四个点所花费的次数为1或0,所以只要当队伍中有一个点Q时,把Q可以花费0次就可以到达的点全部放进队列,然后,就是一个裸的BFS最短路了…
#include<bits/stdc++.h>
using namespace std;
int queue_spend[1000000];//队列中每个位置的最少花费
int queue_x[1000000],queue_y[1000000];//队列中的点
int tail,head,N,M;
int boo[605][605];
int _map[605][605];
//注意:boo判断的是点,_map判断的是边
/*
B C
\ /
A
/ \
D E
A点存的是A这个点和A-E这条边
*/
int now_spead;//记录当前的花费
void add(int x,int y,int spend)//加入队列
{
queue_x[++tail]=x;
queue_y[tail]=y;
queue_spend[tail]=spend;
boo[x][y]=0;
}
void around(int first_x,int first_y)//向四周寻找可以不花费就可以到的点
{
if(boo[first_x-1][first_y-1]&&_map[first_x-1][first_y-1]==0)
//注意当坐标是减时,存边和存点都是减;加时,存边就是当前点对应的边
{add(first_x-1,first_y-1,now_spead);around(first_x-1,first_y-1);}
if(boo[first_x+1][first_y+1]&&_map[first_x][first_y]==0)
{add(first_x+1,first_y+1,now_spead);around(first_x+1,first_y+1);}
if(boo[first_x+1][first_y-1]&&_map[first_x][first_y-1]==1)
{add(first_x+1,first_y-1,now_spead);around(first_x+1,first_y-1);}
if(boo[first_x-1][first_y+1]&&_map[first_x-1][first_y]==1)
{add(first_x-1,first_y+1,now_spead);around(first_x-1,first_y+1);}
}
void write(int out)//输出
{cout<<out<<endl;}
void solve()
{
int i,j;
for(i=0;i<=N+2;i++)//把表赋空
for(j=0;j<=M+2;j++)
boo[i][j]=0;
cin>>N>>M;
char ch;
for(i=1;i<=N;i++)//读入
for(j=1;j<=M;j++)
{
cin>>ch;
if(ch=='/')_map[i][j]=1;//记录下边
else _map[i][j]=0;
//记录下点
boo[i][j]=1;
if(i==N)
boo[i+1][j]=1;
if(j==M)
boo[i][j+1]=1;
if(i==N&&j==M)
boo[i+1][j+1]=1;
}
//队列初始化
tail=1;
head=0;
boo[1][1]=0;
now_spead=0;
around(queue_x[1],queue_y[1]);//把一开始就可以直接到达的点放入队列,并且花费是0
while((++head)<=tail)
{
if(queue_x[head]==N+1&&queue_y[head]==M+1)//找到结果
{
write(queue_spend[head]);
return;
}
if(_map[queue_x[head]-1][queue_y[head]-1]==1&&boo[queue_x[head]-1][queue_y[head]-1])//如果这个方向行走要花费1次的话就入队,比较用0次的早入队了
{
add(queue_x[head]-1,queue_y[head]-1,queue_spend[head]+1);
now_spead=queue_spend[tail];
around(queue_x[tail],queue_y[tail]);//注意这里一定就要把拓展做掉,不然凉凉,我就是在在这里被卡了
}
if(_map[queue_x[head]][queue_y[head]]==1&&boo[queue_x[head]+1][queue_y[head]+1])//以下同理
{
add(queue_x[head]+1,queue_y[head]+1,queue_spend[head]+1);
now_spead=queue_spend[tail];
around(queue_x[tail],queue_y[tail]);
}
if(_map[queue_x[head]-1][queue_y[head]]==0&&boo[queue_x[head]-1][queue_y[head]+1])
{
add(queue_x[head]-1,queue_y[head]+1,queue_spend[head]+1);
now_spead=queue_spend[tail];
around(queue_x[tail],queue_y[tail]);
}
if(_map[queue_x[head]][queue_y[head]-1]==0&&boo[queue_x[head]+1][queue_y[head]-1])
{
add(queue_x[head]+1,queue_y[head]-1,queue_spend[head]+1);
now_spead=queue_spend[tail];
around(queue_x[tail],queue_y[tail]);
}
}
cout<<"NO SOLUTION"<<endl;//无解
}
int main()
{
//这里一直都不会改,就直接放在队伍中
queue_x[1]=1;
queue_y[1]=1;
queue_spend[1]=0;
int T;
cin>>T;//进行T次操作
int i;
for(i=1;i<=T;i++)
solve();
}
QAQ