电路维修
题意
- 从(0,0)走到(n,m)的最小步骤,和斜线相同权重为0,不同权重为1
- 迪杰斯特拉
- 注意怎么判断权重为1,四个方向的格子还有走的点
代码
#include<iostream>
#include<deque>
#include<algorithm>
#include<string>
using namespace std;
typedef pair<int,int>pll;
const int N=1000;
char g[N][N];
bool st[N][N];
int dis[N][N];
int n,m;
int dijistra()
{
int dx[4]={-1,-1,1,1};
int dy[4]={-1,1,1,-1};
int ix[4]={-1,-1,0,0};
int iy[4]={-1,0,0,-1};
char str[5]="\\/\\/";
memset(st,0,sizeof st);
memset(dis,0x3f,sizeof dis);
dis[0][0]=0;
deque<pll>q;
q.push_back(make_pair(0,0));
while(q.size())
{
pll t=q.front();
q.pop_front();
if(st[t.first][t.second]) continue;
st[t.first][t.second] = 1;
for(int i=0;i<4;i++)
{
//走的点
int a=t.first+dx[i];
int b=t.second+dy[i];
if(a<0||a>n||b<0||b>m) continue;
//判断走的权重
int gi=t.first+ix[i];
int gj=t.second+iy[i];
int w=0;
if(g[gi][gj]!=str[i]) w=1;
if(w==0)
{
if(dis[a][b]>dis[t.first][t.second])
{
q.push_front(make_pair(a,b));
dis[a][b]=dis[t.first][t.second];
}
}
if(w==1)
{
if(dis[a][b]>dis[t.first][t.second]+w){
q.push_back(make_pair(a,b));
dis[a][b]=dis[t.first][t.second]+1;
}
}
}
}
return dis[n][m];
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>g[i];
if(n+m&1) cout<<"NO SOLUTION"<<endl;
else{
cout<<dijistra()<<endl;
}
}
return 0;
}