题目链接:https://codeforces.com/problemset/problem/173/B
题意:给你一个n*m的矩阵,你从(1,0)位置射出一个平行于x轴的光,遇到#号的时候,你可以选择转弯然后你要要到达(n,m+1)这个位置,问你最少用多少个#。
思路:把每一行和每一列当成一个顶点,对于每个#,把他所在的行和列连一条权值为1的无向边,然后从第一行到第n行跑一次最短路即可。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 1e5+7;
vector <pair <int, int> > E[N];
int d[N], vis[N], n, m;
void init()
{
for(int i = 0; i <= n; i++)
E[i].clear();
memset(vis, 0, sizeof(vis));
memset(d, 0x3f, sizeof(d));
}
void dijkstra()
{
d[1] = 0;
priority_queue<pair <int, int> >Q;
Q.push({-d[1], 1});
while(!Q.empty())
{
int now = Q.top().second;
Q.pop(); if(vis[now]) continue;
vis[now] = 1;
for(int i = 0; i < E[now].size(); i++)
{
int v = E[now][i].first;
if(!vis[v] && d[v] > d[now] + E[now][i].second)
{
d[v] = d[now] + E[now][i].second;
Q.push({-d[v], v});
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
string str; init();
for(int i = 1; i <= n; i++)
{
cin >> str;
for(int j = 1; j <= m; j++)
{
if(str[j-1] == '#')
{
E[i].push_back({j+n, 1});
E[j+n].push_back({i, 1});
}
}
}
dijkstra();
printf("%d\n",d[n] == inf ? -1 : d[n]);
}