BZOJ2464: 中山市选[2009]小明的游戏
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$不多说。。。
记得清零。。。
附代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #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; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步