洛谷 P1849 [USACO12MAR]拖拉机Tractor

本文介绍了一个利用SPFA算法解决拖拉机如何避开干草堆障碍物的问题。场景设定在一个农场中,拖拉机需要从当前位置移动到坐标原点,但途中会遇到干草堆的阻碍。通过SPFA算法,我们能够找到移除最少数量的干草堆,使得拖拉机能够顺利到达目的地的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

After a long day of work, Farmer John completely forgot that he left his tractor in the middle of the field. His cows, always up to no good, decide to play a prank of Farmer John: they deposit N bales of hay (1 <= N <= 50,000) at various locations in the field, so that Farmer John cannot easily remove the tractor without first removing some of the bales of hay.

The location of the tractor, as well as the locations of the N hay bales, are all points in the 2D plane with integer coordinates in the range 1..1000. There is no hay bale located at the initial position of the tractor. When Farmer John drives his tractor, he can only move it in directions that are parallel to the coordinate axes (north, south, east, and west), and it must move in a sequence of integer amounts. For example, he might move north by 2 units, then east by 3 units. The tractor cannot move onto a point occupied by a hay bale.

Please help Farmer John determine the minimum number of hay bales he needs to remove so that he can free his tractor (that is, so he can drive his tractor to the origin of the 2D plane).

经过一天漫长的工作,农场主 John 完全忘记了他的拖拉机还在场地中央。他的奶牛们总喜欢和他搞些恶作剧,它们在场地的不同位置丢下 N(1 ≤ N ≤ 50,000)堆干草。这样 John 就必须先移走一些干草堆才能将拖拉机开走。

拖拉机和干草堆都可以看作是二维平面上的点,它们的坐标都是整数,坐标范围在 1 到1000 之间。没有那堆干草的坐标和拖拉机的初始坐标一致。John 驾驶拖拉机只能沿着坐标轴的方向移动若干单位长度,比如说,他可以先朝北移动 2 个单位长度,再向东移动 3 个单位长度等等。拖拉机不能移动到干草堆所占据的点。

请你帮助 John 计算一下,最少要移动多少堆干草才能将拖拉机开会坐标原点。

输入输出格式

输入格式:

 

第一行,三个用空格隔开的整数 N、x、y,表示有N 堆干草和拖拉机的起始坐标。

第 2行到第N+1 行,每行两个用空格隔开的整数 x、y,表示每堆干草的坐标。

 

输出格式:

 

一行一个整数,表示最少要移动多少堆干草 John 才能将拖拉机开会坐标原点。

输入输出样例

输入样例#1: 
7 6 3 
6 2 
5 2 
4 3 
2 1 
7 3 
5 4 
6 4 
输出样例#1: 
1

spfa

#include <cstring>
#include <cstdio>
#include <queue>
#define N 1005
using namespace std;
queue<pair<int,int> >q;
bool vis[N][N];
int n,x,y,fx[5]={1,-1,0,0},fy[5]={0,0,-1,1},DIS[N][N],gc[N][N];
void spfa()
{
    q.push(make_pair(x,y)); 
    for(int nx,ny;!q.empty();)
    {
        nx=q.front().first,ny=q.front().second;
        q.pop();
        vis[nx][ny]=false;
        for(int i=0;i<4;++i)
        {
            int tx=nx+fx[i],ty=ny+fy[i];
            if(tx>=0&&tx<=1001&&ty>=0&&ty<=1001&&DIS[tx][ty]>DIS[nx][ny]+gc[tx][ty])
            {
                DIS[tx][ty]=DIS[nx][ny]+gc[tx][ty];
                if(!vis[tx][ty])
                {
                    vis[tx][ty]=true;
                    q.push(make_pair(tx,ty));
                }
            }
        }
    }
}
int main(int argc,char *argv[])
{
    scanf("%d%d%d",&n,&x,&y);
    for(int a,b,i=1;i<=n;++i)
    {
        scanf("%d%d",&a,&b);
        gc[a][b]=1;
    }
    memset(DIS,0x3f,sizeof(DIS));
    DIS[x][y]=0;
    spfa();
    printf("%d\n",DIS[0][0]);
    return 0;
}

 




转载于:https://www.cnblogs.com/ruojisun/p/7742176.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值