题目描述
Casper is designing an electronic circuit on a N \times MN×M rectangular grid plate. There are N \times MN×M square tiles that are aligned to the grid on the plate. Two (out of four) opposite corners of each tile are connected by a wire.
A power source is connected to the top left corner of the plate. A lamp is connected to the bottom right corner of the plate. The lamp is on only if there is a path of wires connecting power source to lamp. In order to switch the lamp on, any number of tiles can be turned by 90° (in both directions).
In the picture above the lamp is off. If any one of the tiles in the second column from the right is turned by 90° , power source and lamp get connected, and the lamp is on.
Write a program to find out the minimal number of tiles that have to be turned by 90° to switch the lamp on.
输入格式:
The first line of input contains two integer numbers NN and MM, the dimensions of the plate. In each of the following NN lines there are MM symbols – either \ or / – which indicate the direction of the wire connecting the opposite vertices of the corresponding tile.
输出格式:
There must be exactly one line of output. If it is possible to switch the lamp on, this line must contain only one integer number: the minimal number of tiles that have to be turned to switch on the lamp. If it is not possible, output the string: NO SOLUTION
输入样例:
3 5
\\/\\
\\///
/\\\\
输出样例:
1
说明
对于所有数据,
解析:
对角线建边跑最短路即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int inf=1e9;
const int Max=2000010;
int n,m,size;
int first[251005],dis[251005],vis[251005];
char d[505][505];
struct shu{int next,to,len;};
shu edge[Max];
inline int get_int()
{
int x=0,f=1;
char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline void build(int x,int y,int z)
{
edge[++size].next=first[x];
first[x]=size;
edge[size].to=y,edge[size].len=z;
}
inline void dijkstra()
{
priority_queue<pair<int,int> >q;
for(int i=0;i<=n*m;i++) dis[i]=inf;
dis[1]=0,q.push(make_pair(0,1));
while(!q.empty())
{
int point=q.top().second;q.pop();
if(vis[point])continue;vis[point]=1;
for(int u=first[point];u;u=edge[u].next)
{
int to=edge[u].to;
if(dis[to] > dis[point] + edge[u].len)
{
dis[to] = dis[point] + edge[u].len;
q.push(make_pair(-dis[to],to));
}
}
}
}
int main()
{
n=get_int(),m=get_int();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) scanf("%c",&d[i][j]);
scanf("\n");
}
n++,m++;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(j!=m)
{
if(i!=1) build((i-1)*m+j,(i-2)*m+j+1,d[i-1][j]=='/' ? 0 : 1);
if(i!=n) build((i-1)*m+j,i*m+j+1,d[i][j]=='/' ? 1 : 0);
}
if(j!=1)
{
if(i!=1) build((i-1)*m+j,(i-2)*m+j-1,d[i-1][j-1]=='/' ? 1 : 0);
if(i!=n) build((i-1)*m+j,i*m+j-1,d[i][j-1]=='/' ? 0 : 1);
}
}
dijkstra();
if(dis[n*m]==dis[0]) cout<<"NO SOLUTION";
else cout<<dis[n*m];
return 0;
}