Tractor S
洛谷题号
思路 :本题数据不是很大,顶多1000^2;再加上本题没有要求路径最短,只是要求最小挪动干草堆的代价。
最好的解法就是:01BFS
1、两个队列,一个是代价为0的队列,一个是代价为1的队列。
2.进行BFS,不断改进松弛
3.大思想:尽量走没有干草堆的地方,避开有干草的地方,直到走不下去为止。
#include <bits/stdc++.h>
using namespace std;
const int MAXE=1002;
struct Point
{
int x, y;
Point (int _x, int _y) { x = _x; y = _y; }
Point () {x=y=0;}
};
queue<Point> q0,q1;
int a[MAXE][MAXE], d[MAXE][MAXE];
int relax(int nowx,int nowy,int x,int y)
{
if (x>=0&&x<=1001 &&y>=0&&y<=1001&&(d[x][y]==0||d[nowx][nowy]+a[x][y]<d[x][y])) //判断是否合法
{
d[x][y]=d[nowx][nowy]+a[x][y];
if(a[x][y]==0) q0.push(Point(x,y));
else q1.push(Point(x,y));
}
}
int main()
{
Point p;
int n;
//freopen ("tractor.in", "r", stdin);
//freopen ("tractor.out", "w", stdout);
ios::sync_with_stdio(false);
cin>>n>>p.x>>p.y;
d[p.x][p.y]=1;//先把拖拉机的位置设为1,防止日后重复来过
q0.push(p);
for (int i=0;i<n;++i)
{
cin>>p.x>>p.y;
a[p.x][p.y]=1;
}
while (!q0.empty()||!q1.empty())
{
if (q0.empty()) //如果代价为0的队列为空了
while (!q1.empty())
{
q0.push(q1.front());//就把代价为1的给拿过来
q1.pop();
}
p=q0.front(); q0.pop();
relax(p.x,p.y,p.x-1,p.y);//四个方向,不断松弛
relax(p.x,p.y,p.x+1,p.y);
relax(p.x,p.y,p.x,p.y-1);
relax(p.x,p.y,p.x,p.y+1);
}
cout<<d[0][0]-1;//因为一开始拖拉机的位置多了1,再减去
return 0;
}
推荐两道01BFS的题目:https://www.luogu.com.cn/problem/P4162 https://www.luogu.com.cn/problem/SP22393