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

来源:互联网 发布:软件开发过程检测规范 编辑:程序博客网 时间:2024/05/01 06:55

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。

Source



传送门
比较简单的题目……相邻的位置连边就好了。
当然这样的话先把二维点转化到一维,然后连完边,
再接下来……就是最短路了。。。

不想写dij+heap
结果SPFA的队列长度爆了几次……
气死了!
直接开循环队列!

好吧,转化到一维的报应就是时间比较慢……
400多ms啦


#include<bits/stdc++.h>using namespace std;int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}const int N=505,M=300005;int n,m,Ecnt;int dis[N*N],Q[M];bool vis[N*N];char s[N][N];struct Edge{int next,to,val;}E[N*N<<1]; int head[N*N];int vertex(int i,int j){return (i-1)*m+j;}void add(int u,int v,int w){E[++Ecnt].next=head[u];E[Ecnt].to=v;E[Ecnt].val=w;head[u]=Ecnt;E[++Ecnt].next=head[v];E[Ecnt].to=u;E[Ecnt].val=w;head[v]=Ecnt;}void build(){for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){if (i-1) add(vertex(i,j),vertex(i-1,j),s[i][j]!=s[i-1][j]);if (j-1) add(vertex(i,j),vertex(i,j-1),s[i][j]!=s[i][j-1]);}}int SPFA(int sta,int end){memset(vis,0,sizeof(vis));memset(dis,60,sizeof(dis));int h=0,tail=1;Q[0]=sta; dis[sta]=0;while (h!=tail){int u=Q[h];h=(h+1)%M;vis[u]=0;for (int i=head[u];i;i=E[i].next)if (dis[u]+E[i].val<dis[E[i].to]){dis[E[i].to]=dis[u]+E[i].val;if (!vis[E[i].to]){vis[E[i].to]=1; Q[tail]=E[i].to;tail=(tail+1)%M;}}}return dis[end];}int main(){int x0,y0,x1,y1;while (1){n=read(),m=read();if (!n) break;Ecnt=0;memset(head,0,sizeof(head));for (int i=1;i<=n;i++)scanf("%s",s[i]+1);build();x0=read(),y0=read(),x1=read(),y1=read();x0++,y0++,x1++,y1++; printf("%d\n",SPFA(vertex(x0,y0),vertex(x1,y1)));}return 0;}