街区最短路径问题
时间限制:
3000 ms | 内存限制:65535 KB
难度:
4
- 描述
-
一个街区有很多住户,街区的街道只能为东西、南北两种方向。
住户只可以沿着街道行走。
各个街道之间的间隔相等。
用(x,y)来表示住户坐在的街区。
例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。
现在要建一个邮局,使得各个住户到邮局的距离之和最少。
求现在这个邮局应该建在那个地方使得所有住户距离之和最小;
- 输入
-
第一行一个整数n<20,表示有n组测试数据,下面是n组数据;
每组第一行一个整数m<20,表示本组有m个住户,下面的m行每行有两个整数0<x,y<100,表示某个用户所在街区的坐标。
m行后是新一组的数据; - 输出
- 每组数据输出到邮局最小的距离和,回车结束;
- 样例输入
-
2 3 1 1 2 1 1 2 5 2 9 5 20 11 9 1 1 1 20
- 样例输出
-
2 44
PS:我们可以将坐标的距离问题,分解为x方向上、y方向上一个点到对应不同x、y的和的最小值(曼哈顿距离)
C/C++代码实现(AC):1 #include <iostream> 2 #include <algorithm> 3 #include <climits> 4 #include <cstdio> 5 6 using namespace std; 7 8 int main() { 9 int N; 10 scanf("%d", &N); 11 while (N --) { 12 int n, X[25], Y[25], ans = 0; 13 scanf("%d", &n); 14 for(int i = 0; i < n; ++i) 15 scanf("%d %d", &X[i], &Y[i]); 16 sort(X, X+n, less<int>()); 17 sort(Y, Y+n, less<int>()); 18 19 for(int i = 0; i < n/2; ++ i) 20 ans += X[n-1-i] - X[i] + Y[n-1-i] - Y[i]; 21 printf("%d\n", ans); 22 } 23 return 0; 24 }
暴力(C/C++代码实现(AC)):
1 #include <iostream> 2 #include <algorithm> 3 #include <climits> 4 5 using namespace std; 6 7 int main() { 8 int N; 9 cin >>N; 10 while (N --) { 11 int m, minn=INT_MAX, X, Y; 12 cin >>m; 13 struct node{ 14 int x, y; 15 }P[102]; 16 for (int i=0; i<m; ++i) cin >>P[i].x >>P[i].y; 17 18 for (int i=1; i<=99; ++i) { 19 for (int j=1; j<=99; ++j) { 20 int cnt=0; 21 for (int k=0; k<m; ++k) { 22 cnt += abs(P[k].x-i) + abs(P[k].y-j); 23 } 24 if (cnt<minn) { 25 minn = cnt; 26 X=i; Y=j; 27 } 28 } 29 } 30 cout <<minn <<endl; 31 } 32 return 0; 33 }