街区最短路径问题
时间限制:
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
一看到最短路径,我就觉得是弗洛伊德或者迪杰斯特拉的算法
仔细一看,好像不对啊,又脑洞大开想到了多边形重心……但是应该也不对,
后来找答案,有暴力方法就是列举横竖100*100个点看哪个点最小,
更主流的方法是:设使各个点到(x,y)的距离和最小
那么sum = |所有点的横坐标-x的绝对值|求和 + |所有点的纵坐标 - y |求和
假设有已经排序了的5个点
已知 |x5-x1| = |x1-x|+|x5-x| x为中点横坐标
所以sum = x5-x1+x4-x2+x3-x3
所以代码就是酱婶儿的
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int MAX = 25; int a[MAX]; int b[MAX]; int c[MAX]; int abss(int x){//取绝对值的函数 if(x<0) return -x; else return x; } int main(){ int n,m; cin>>n; for(int i=0;i<n;i++){ memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); cin>>m; for(int j=0;j<m;j++){ cin>>a[j]>>b[j]; } sort(a,a+m); sort(b,b+m); int sum=0; for(int j=0;j<m/2;j++){ sum+=a[m-j-1]-a[j]+b[m-j-1]-b[j]; } cout<<sum<<endl; } return 0; }