题目背景
Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上。在她无依无靠的时候,善良的运输队员Mark 和James 收留了她。Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙。
题目描述
有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障。飞行车的电路板设计很奇葩,如下图所示:
输入输出格式
输入格式:
输入文件包含多组测试数据。第一行包含一个整数T 表示测试数据的数目。对于每组测试数据,第一行包含正整数 R 和C,表示电路板的行数和列数。之后 R 行,每行C 个字符,字符是"/"和"\"中的一个,表示标准件的方向。对于40% 的数据,R,C≤5。对于 100% 的数据,R,C≤500,T≤5。
输出格式:
对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
如果无论怎样都不能使得电源和发动机之间连通,输出 NO SOLUTION。
输入输出样例
输入样例#1:
1 3 5 \\/\\ \\/// /\\\\
输出样例#1:
1
样例的输入对于题目描述中的情况。需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。
题解
这题的玄妙之处在于建图,把一个格分成4个点,这样就分成了n+1行,m+1列,每一条线的方向连接这个格所包含的四个点边权设为1或0,。这样跑一边最短路就行了,这是一个稠密图,所以用dijkstra吧,spfa我不知道能不能过,感觉不能,时间卡的挺紧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 100000000
using namespace std;
const int maxn=510;
char s[maxn];
int pre[maxn*maxn*4],last[maxn*maxn],other[maxn*maxn*4],num,w[maxn*maxn*4];
int d[maxn*maxn],t,n,m;;
void add(int x,int y,int z){
num++;
pre[num]=last[x];
last[x]=num;
other[num]=y;
w[num]=z;
}
struct node{
int dis,i;
};
priority_queue<node>q;
bool operator<(node a,node b) {
return a.dis>b.dis;
}
inline void dijkstra(){
memset(d,0x3f,sizeof(d));
q.push((node){0,1});
d[1]=0;
while(!q.empty()){
node t=q.top();
q.pop();
if(t.dis!=d[t.i]) continue;
for(int i=last[t.i];i;i=pre[i]){
int v=other[i];
if(t.dis+w[i]<d[v]){
d[v]=t.dis+w[i];
q.push((node){d[v],v});
}
}
}
}
int main(){
scanf("%d",&t);
while(t--){
//memset(pre,0,sizeof(pre));
num=0;
memset(last,0,sizeof(last));
//memset(other,0,sizeof(other));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",s);
for(int j=1;j<=m;j++){
if(s[j-1]=='/'){
int pos1=(i-1)*(m+1)+j;//左上
int pos2=i*(m+1)+j+1;//右下
int pos3=(i-1)*(m+1)+j+1;//右上
int pos4=i*(m+1)+j;//左下
add(pos1,pos2,1);
add(pos2,pos1,1);
add(pos3,pos4,0);
add(pos4,pos3,0);
}
else{
int pos1=(i-1)*(m+1)+j;
int pos2=i*(m+1)+j+1;
int pos3=(i-1)*(m+1)+j+1;
int pos4=i*(m+1)+j;
add(pos1,pos2,0);
add(pos2,pos1,0);
add(pos3,pos4,1);
add(pos4,pos3,1);
}
}
}
dijkstra();
if(d[(n+1)*(m+1)]==d[0]) printf("NO SOLUTION\n");
else printf("%d\n",d[(n+1)*(m+1)]);
}
return 0;
}