[USACO12MAR]拖拉机

题目描述

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的话;

代码

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=1e3+10;
 4 int N,x,y,a,b,c,d;
 5 int s[maxn][maxn];
 6 bool map[maxn][maxn];
 7 int q[maxn*maxn][2],head,tail;
 8 int hb[4]={1,-1,0,0};
 9 int lb[4]={0,0,1,-1};
10 void SPFA(){
11     s[x][y]=0,q[tail][0]=x,q[tail++][1]=y;
12     while(head!=tail){
13         a=q[head][0],b=q[head++][1],head%=maxn*maxn;
14         for(int i=0;i<4;i++){
15             c=a+hb[i],d=b+lb[i];
16             if(c>=0&&c<=1001&&d>=0&&d<=1001)
17             if(s[c][d]>s[a][b]+map[c][d]){
18                 s[c][d]=s[a][b]+map[c][d];
19                 q[tail][0]=c,q[tail++][1]=d,tail%=maxn*maxn;
20             }
21         }
22     }
23 }
24 int main(){
25     scanf("%d%d%d",&N,&x,&y);
26     for(int i=1;i<=N;i++) scanf("%d%d",&a,&b),map[a][b]=1;
27     memset(s,30,sizeof(s));SPFA();
28     printf("%d\n",s[0][0]);
29     return 0;
30 }

 

posted @ 2017-10-27 14:14  J_william  阅读(236)  评论(0编辑  收藏  举报