拖拉机
干了一整天的活,农夫约翰完全忘记了他把拖拉机落在田地中央了。
他的奶牛非常调皮,决定对约翰来场恶作剧。
她们在田地的不同地方放了 N 捆干草,这样一来,约翰想要开走拖拉机就必须先移除一些干草捆。
拖拉机的位置以及 N 捆干草的位置都是二维平面上的整数坐标点。
拖拉机的初始位置上没有干草捆。
当约翰驾驶拖拉机时,他只能沿平行于坐标轴的方向(北,南,东和西)移动拖拉机,并且拖拉机必须每次移动整数距离。
例如,驾驶拖拉机先向北移动 2 单位长度,然后向东移动 3 单位长度。
拖拉机无法移动到干草捆占据的位置。
请帮助约翰确定他需要移除的干草捆的最小数量,以便他能够将拖拉机开到二维平面的原点。
输入格式
第一行包含三个整数:N 以及拖拉机的初始位置 (x,y)。
接下来 N 行,每行包含一个干草捆的位置坐标 (x,y)。
输出格式
输出约翰需要移除的干草捆的最小数量。
数据范围
1≤N≤50000,
1≤x,y≤1000
输入样例:
7 6 3
6 2
5 2
4 3
2 1
7 3
5 4
6 4
输出样例:
1
双端队列的广搜解决图中只有边权为0,和边权为1的最短路问题
假设:如果需要移动干草堆,那么边权为1,如果不需要移动干草堆那么边权为0
双端队列 *** 作:每次取出队头,并拓展可以到达的点,并做判断如下
- 如果这个点有干草堆,边权为1,并且被取出的点更新过的话,就把这个点加入队尾(可继续更新)
- 如果这个点没有干草堆,边权为0,并且被取出的点更新过的话,把这个点加入队头(可继续更新)
#include#include #include #include using namespace std; #define x first #define y second typedef pair PII; const int N = 1005; int dist[N][N]; bool g[N][N],st[N][N]; deque q; int nextt[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; int bfs(int sx,int sy) { memset(dist,0x3f,sizeof dist); dist[sx][sy]=0; deque q; q.push_back({sx,sy}); while(q.size()){ auto t = q.front(); q.pop_front(); for(int i=0; i<4; ++i){ int nx = t.x+nextt[i][0], ny = t.y+nextt[i][1]; if(nx<0 || nx>=N || ny<0 || ny>=N) continue; int w=0; if(g[nx][ny]) w=1; if(dist[nx][ny] > dist[t.x][t.y]+w){ dist[nx][ny] = dist[t.x][t.y]+w; if(g[nx][ny]) q.push_back({nx,ny}); else q.push_front({nx,ny}); } } } return dist[0][0]; } int main() { int n,sx,sy; scanf("%d%d%d",&n,&sx,&sy); while(n--){ int x,y; scanf("%d%d",&x,&y); g[x][y] = true; } printf("%dn",bfs(sx,sy)); return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)