题面描述
思考
建边贼烦,转化一下就好了。
我这里是将二维图压成了一维来存,因为输入是边,所以点要自己弄出来,矩形也要(n+1)(m+1)的,之后用双端队列来优化一下(不用应该也行)。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<deque>
using namespace std;
const int N=3e5+10;
const int M=1e6+10;
struct edge{int x,y,c,next;}a[M];int len,last[N];
void ins(int x,int y,int c)
{
a[++len].x=x,a[len].y=y;a[len].c=c,a[len].next=last[x];last[x]=len;
}
char s[510][510];
int d[N];int st,ed;
deque<int>q;
int n,m;
int calc(int i,int j){return i*(m+1)+j+1;}
void bfs()
{
while(!q.empty())q.pop_front();
for(int i=0;i<=ed;i++)d[i]=-1;d[st]=0;
q.push_front(st);
while(!q.empty())
{
int x=q.front();q.pop_front();
if(x==ed){printf("%d\n",d[x]);return;}
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(d[y]==-1||d[y]>d[x]+a[k].c)
{
d[y]=d[x]+a[k].c;
if(!a[k].c)
{
q.push_front(y);
}
else
{
q.push_back(y);
}
}
}
}
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);st=1,ed=(n+1)*(m+1);
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
if((n&1)!=(m&1)){puts("NO SOLUTION");continue;}
len=0;memset(last,0,sizeof(last));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(s[i][j]=='/')
{
ins(calc(i-1,j-1),calc(i,j),1);
ins(calc(i,j),calc(i-1,j-1),1);
ins(calc(i-1,j),calc(i,j-1),0);
ins(calc(i,j-1),calc(i-1,j),0);
}
else
{
ins(calc(i-1,j-1),calc(i,j),0);
ins(calc(i,j),calc(i-1,j-1),0);
ins(calc(i-1,j),calc(i,j-1),1);
ins(calc(i,j-1),calc(i-1,j),1);
}
}
}
bfs();
}
return 0;
}