链接
题目描述
样例输入
1
3 5
\\/\\
\\///
/\\\\
样例输出
1
思路
傻逼题,每个格子视作一个节点,然后相邻的格子就连边,然后再考虑要不要转向,如果要就把边权设为1,否则为0,然后求最短路就可以了
要用双端队列
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<deque>
using namespace std;
char c;
int n, m, t, T;
int vis[1000500], Ans[1000500], h[1000500];
struct lL
{
int to, next, val;
}L[1000500];
char read() {
char cc = getchar();
while (cc != '/' && cc != '\\') cc = getchar();
return cc;
}//读入处理(YbtOJ传统艺能)
void Connect(int x, int y, int xx, int yy, int val)
{
int num1 = (x - 1) * (m + 1) + y;
int num2 = (xx - 1) * (m + 1) + yy;
L[++t] = (lL){
num2, h[num1], val};
h[num1] = t;
L[++t] = (lL){
num1, h[num2], val};
h[num2] = t;
}//连边
void BFS()
{
deque<int>Q;
Q.push_back(1);
vis[1] = 1;
while(Q.size())
{
int tot = Q.front();
vis[tot] = 1;
Q.pop_front();
for(int i = h[tot]; i; i = L[i].next)
{
int to = L[i].to;
if(L[i].val + Ans[tot] < Ans[to])
{
Ans[to] = Ans[tot] + L[i].val;
if(!vis[to]) {
if(L[i].val == 0) Q.push_front(to);
else Q.push_back(to);
}
}//最短路
}
}
}
int main()
{
scanf("%d", &T);
while(T--)
{
memset(Ans, 0x7f, sizeof(Ans));
memset(vis, 0, sizeof(vis));
memset(L, 0, sizeof(L));
memset(h, 0, sizeof(h));
scanf("%d%d", &n, &m); t = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
c = read();
if(c == '/') {
Connect(i, j, i + 1, j + 1, 1);
Connect(i + 1, j, i, j + 1, 0);
}
else {
Connect(i, j, i + 1, j + 1, 0);
Connect(i + 1, j, i, j + 1, 1);
}
}
Ans[1] = 0;
BFS();
if(Ans[(n + 1) * (m + 1)] < 1e6)
printf("%d\n", Ans[(n + 1) * (m + 1)]);
else printf("NO SOLUTION\n");
}
return 0;
}