【Codeforces Round #442 (Div. 2) D】Olya and Energy Drinks

【链接】 我是链接,点我呀:)
【题意】

给一张二维点格图,其中有一些点可以走,一些不可以走,你每次可以走1..k步,问你起点到终点的最短路.

【题解】

不能之前访问过那个点就不访问了。->即k那一层循环直接break; 因为可能出现这种 ax aa aa 然后起点是(3,2)终点是(1,1);然后k=3 bfs的时候,第一步,走到了(2,2)和(3,1); 但是接下来,如果(2,2)先走的话,就会先走到(2,1); 而(3,1)认为(2,2)走过了,就不往下走了。 ->但实际上他可以一步走到(1,1)的。。 就这个地方要注意啦。 为了防止这种情况。 就写一个二维的spfa吧。 除非遇到>否则不break;

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 1000;
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
const int INF = 0x3f3f3f3f;

queue <pair<int,int> > dl;
bool inque[N+10][N+10];
char s[N+10][N+10];
int mi[N+10][N+10];
bool bo[N+10][N+10];
int n,m,k,x1,y1,x2,y2;

int main(){	
//	freopen("rush.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&k);
	for (int i = 1;i <= n;i++){
		scanf("%s",s[i]+1);
	}
	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
	for (int i = 1;i <= n;i++)
		for (int j = 1;j <= m;j++)
			if (s[i][j]=='#')
				bo[i][j] = 0;
			else
				bo[i][j] = 1;
	memset(mi,INF,sizeof mi);						
	mi[x1][y1] = 0;
	inque[x1][y1] = true;
	dl.push(make_pair(x1,y1));
	while (!dl.empty()){
	 	int x = dl.front().first,y = dl.front().second;
	 	dl.pop();
	 	inque[x][y] = false;
	 	for (int i = 0;i < 4;i++){
	 		for (int j = 1;j <= k;j++){
                		int xx = x + j*dx[i],yy = y + j*dy[i];
                		if (xx>=1 && xx <= n && yy>=1 && yy <= m && bo[xx][yy]){
                			if (mi[xx][yy] >= mi[x][y] + 1){
                			 	mi[xx][yy] = mi[x][y] + 1;
                			 	if (!inque[xx][yy]){
                			 	 	inque[xx][yy] = 1;
                			 	 	dl.push(make_pair(xx,yy));
                			 	}
                			}else break;
                		}else break;
	 		}
	 	}
	}
	if (mi[x2][y2]==INF)
		puts("-1");
	else
		printf("%d
",mi[x2][y2]);
	return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7731565.html