Description
小明最近喜欢玩一个游戏。给定一个n * m的棋盘,上面有两种格子#和@。
游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。
如果移动到同一类型的格子,则费用是0,否则费用是1。
请编程计算从起始位置移动到目标位置的最小花费。
Input
输入文件有多组数据。
输入第一行包含两个整数n,m,分别表示棋盘的行数和列数。
输入接下来的n行,每一行有m个格子(使用#或者@表示)。
输入接下来一行有四个整数x1, y1, x2, y2,分别为起始位置和目标位置。
当输入n,m均为0时,表示输入结束。
Output
对于每组数据,输出从起始位置到目标位置的最小花费。每一组数据独占一行。
Sample Input
2 2
@#
#@
0 0 1 1
2 2
@@
@#
0 1 1 0
0 0
@#
#@
0 0 1 1
2 2
@@
@#
0 1 1 0
0 0
Sample Output
2
0
0
HINT
对于100%的数据满足:1 < = n, m <= 500。
题解Here!
本来以为是什么$DP$神题。。。
看完题发现这就是一道最短路沙茶题。。。
$Spfa$不多说。。。
记得清零。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define MAXN 250010
#define MAXM 510
#define MAX 999999999
using namespace std;
const int fx[4]={1,-1,0,0},fy[4]={0,0,1,-1};
int n,m,s,t,c=1;
char g[MAXM][MAXM];
int head[MAXN],path[MAXN];
bool vis[MAXN];
struct Graph{
int next,to,w;
}a[MAXN<<3];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline int id(int x,int y){return (x-1)*m+y;}
inline bool check(int x,int y){
if(x<1||x>n||y<1||y>m)return true;
return false;
}
inline int relax(int u,int v,int w){
if(path[v]>path[u]+w){
path[v]=path[u]+w;
return 1;
}
return 0;
}
inline void add(int u,int v,int w){
a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
}
void spfa(){
int u,v;
queue<int> q;
for(int i=1;i<=n*m;i++){path[i]=MAX;vis[i]=false;}
path[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty()){
u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i;i=a[i].next){
v=a[i].to;
if(relax(u,v,a[i].w)&&!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
printf("%d\n",path[t]);
}
void init(){
int u,v,w;
c=1;
memset(head,0,sizeof(head));
for(int i=1;i<=n;i++)scanf("%s",g[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
u=id(i,j);
for(int k=0;k<4;k++){
if(check(i+fx[k],j+fy[k]))continue;
v=id(i+fx[k],j+fy[k]);w=(g[i][j]==g[i+fx[k]][j+fy[k]]?0:1);
add(u,v,w);
}
}
u=read()+1;v=read()+1;
s=id(u,v);
u=read()+1;v=read()+1;
t=id(u,v);
}
int main(){
while(1){
n=read();m=read();
if(n==0&&m==0)break;
init();
spfa();
}
return 0;
}