[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
#include
#include
#include
#include
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;
}

你可能感兴趣的:(bzoj,最长/短路)