1. 程式人生 > 實用技巧 >題解 P4554 小明的遊戲

題解 P4554 小明的遊戲

Link

P4554 小明的遊戲

Solve

一道非常典型的spfa變形,將相同的邊權定為0,不同的定為1,然後直接刷spfa就好了
but為啥我wa了,對拍還不死,求神仙看看。

Code

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
const int maxn=505;
const int flg[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int n,m,Q[maxn*maxn][2],dis[maxn][maxn],vis[maxn][maxn],sx,sy,dx,dy;
char a[maxn][maxn];
bool check(int x,int y){return x<1||x>n||y<1||y>m;}
int spfa(){
	int hed=0,til=1;
	memset(dis,63,sizeof dis);
	memset(vis,0,sizeof vis);
	Q[til][0]=sx,Q[til][1]=sy,vis[sx][sy]=1;dis[sx][sy]=0;
	while(hed!=til){
		hed=(hed+1)%(maxn*maxn);vis[Q[hed][0]][Q[hed][1]]=0;
		for(int k=0;k<4;k++){
			if(check(Q[hed][0]+flg[k][0],Q[hed][1]+flg[k][1]))continue;
			int d=(a[Q[hed][0]][Q[hed][1]]!=a[Q[hed][0]+flg[k][0]][Q[hed][1]+flg[k][1]]);
			if(dis[Q[hed][0]][Q[hed][1]]+d<dis[Q[hed][0]+flg[k][0]][Q[hed][1]+flg[k][1]]){
				dis[Q[hed][0]+flg[k][0]][Q[hed][1]+flg[k][1]]=dis[Q[hed][0]][Q[hed][1]]+d;
				if(!vis[Q[hed][0]+flg[k][0]][Q[hed][1]+flg[k][1]]){
					til=(til+1)%(maxn*maxn);
					vis[Q[hed][0]+flg[k][0]][Q[hed][1]+flg[k][1]]=1;
					Q[til][0]=Q[hed][0]+flg[k][0];Q[til][1]=Q[hed][1]+flg[k][1];
				}
			}
		}
	}
	return dis[dx][dy];
}
int main(){
	freopen("P4554.in","r",stdin);
	freopen("P4554.out","w",stdout);
	while(1){
		scanf("%d%d",&n,&m);
		if(n==0||m==0)break;
		memset(a,0,sizeof a);
		for(int i=1;i<=n;i++){
			getchar();
			for(int j=1;j<=m;j++)a[i][j]=getchar();
		}
		sx=read()+1;sy=read()+1,dx=read()+1,dy=read()+1;
		printf("%d\n",spfa());
	}
	return 0;
}