1. 程式人生 > >[bzoj2464][最短路]小明的遊戲

[bzoj2464][最短路]小明的遊戲

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

Sample Output

2

0

HINT

對於100%的資料滿足:1 < = n, m <= 500。

題解

最短路不解釋

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath> using namespace std; const int dx[4]={0,-1,0,1}; const int dy[4]={-1,0,1,0}; struct node { int x,y; }list[510000];int head,tail; char mp[501][501]; int d[501][501]; bool v[501][501]; int n,m,stx,sty,edx,edy; int chk(int x,int y,int u,int v) { if(mp[x][y]!=mp[u][v])return 1; return
0; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0 && m==0)break; for(int i=1;i<=n;i++)scanf("%s",mp[i]+1); scanf("%d%d%d%d",&stx,&sty,&edx,&edy); stx++;sty++;edx++;edy++; memset(d,63,sizeof(d)); d[stx][sty]=0; memset(v,false,sizeof(v)); list[1].x=stx;list[1].y=sty;v[stx][sty]=true; head=1;tail=2; while(head!=tail) { node tmp=list[head]; for(int k=0;k<=3;k++) { int x=tmp.x+dx[k],y=tmp.y+dy[k]; if(x<1 || x>n || y<1 || y>m)continue; int op=chk(tmp.x,tmp.y,x,y); if(d[x][y]>d[tmp.x][tmp.y]+op) { d[x][y]=d[tmp.x][tmp.y]+op; if(v[x][y]==false) { v[x][y]=true; list[tail].x=x;list[tail].y=y; tail++;if(tail==n*m+1)tail=1; } } } v[tmp.x][tmp.y]=false; head++;if(head==n*m+1)head=1; } printf("%d\n",d[edx][edy]); } return 0; }