BZOJ[2464]中山市选[2009]小明的游戏 SPFA

来源:互联网 发布:域名备案查询 编辑:程序博客网 时间:2024/05/01 14:45

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=2464

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。

SPFA….
最近怎么越来越水了..

代码如下:

#include<cstring>#include<ctype.h>#include<cstdio>#include<queue>#define N 505using namespace std;int fx[5]={0,1,0,-1,0};int fy[5]={0,0,1,0,-1};inline int read(){    int x=0,f=1;char c;    do{c=getchar();if(c=='-') f=-1;}while(!isdigit(c));    do x=(x<<3)+(x<<1)+c-'0',c=getchar();while(isdigit(c));    return x*f;}struct Point{    int x,y;    Point(int _=0,int __=0):x(_),y(__){}}s,t;queue<Point>q;bool vis[N][N];int a[N][N],dis[N][N],n,m,xx,yy;char c;inline bool inrange(int x,int y){    if(x<=0 || y<=0 || x>n || y>m) return false;    return true;}inline int calc(int x,int y,int xx,int yy){    if(a[x][y]==a[xx][yy]) return 0;    return 1;}inline void spfa(){    while(!q.empty()) q.pop();    memset(dis,0x7f7f7f7f,sizeof dis);    memset(vis,0,sizeof vis);    dis[s.x][s.y]=0;vis[s.x][s.y]=true;    q.push(s);    while(!q.empty()){        Point x=q.front();        q.pop();vis[x.x][x.y]=false;        for(int i=1;i<=4;i++){            xx=x.x+fx[i];yy=x.y+fy[i];            if(!inrange(xx,yy)) continue;            if(dis[x.x][x.y]+calc(x.x,x.y,xx,yy)<dis[xx][yy]){                dis[xx][yy]=dis[x.x][x.y]+calc(x.x,x.y,xx,yy);                if(!vis[xx][yy]){                    vis[xx][yy]=true;                    q.push(Point(xx,yy));                }            }        }    }}int main(){    while(""){        n=read();m=read();        if(!n && !m) break;        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++){                do c=getchar(); while(c!='@' && c!='#');                a[i][j]=(c=='@'?1:0);            }        s.x=read()+1;s.y=read()+1;        t.x=read()+1;t.y=read()+1;        spfa();        printf("%d\n",dis[t.x][t.y]);    }return 0;}
原创粉丝点击