博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法笔记_178:历届试题 邮局(Java)
阅读量:5033 次
发布时间:2019-06-12

本文共 3503 字,大约阅读时间需要 11 分钟。

目录

 


1 问题描述

问题描述
  C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。
  现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。
输入格式
  输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。
  接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。
  接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。
  在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。
输出格式
  输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)
样例输入
5 4 2
0 0
2 0
3 1
3 3
1 1
0 1
1 0
2 1
3 2
样例输出
2 4
数据规模和约定
  对于30%的数据,1<=n<=10,1<=m<=10,1<=k<=5;
  对于60%的数据,1<=m<=20;
  对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。

 

 

 


2 解决方案

本题主要考查DFS搜索和剪枝,具体解释请看注释。

 

具体代码如下:

 

import java.util.Scanner;public class Main {    public static int n, m, k;    public static double[][] distance;    //distanc[i][j]表示第i个村庄到第j个邮局的直线距离    public static int[] answer;  //存放最终选中的k个邮局编号    public static double minSum;   //表示选中k个邮局的最小距离和        public void init() {        distance = new double[n + 1][m + 1];        answer = new int[k + 1];        minSum = Double.MAX_VALUE;    }        /*     * 参数count:表示已经选中的邮局个数     * 参数current:表示DFS目前遍历到的邮局编号     * 参数minDis:minDis[i]表示村庄i到已选中邮局中的最短距离     * 参数tempAns:存放目前遍历过程中已经选中的邮局编号     */    public void dfs(int count, int current, double[] minDis, int[] tempAns) {        if(count == k) {  //当已经选中k个邮局时            double tempSum = 0;            for(int i = 1;i <= n;i++)                tempSum += minDis[i];            if(tempSum < minSum) {                minSum = tempSum;                for(int i = 1;i <= k;i++)                    answer[i] = tempAns[i];            }            return;        } else if(k - count <= m - current && current <= m) { //表示在剩下未选中的邮局个数多于还需要选中的邮局个数            boolean judge = false;   //用于判断当前选中的邮局current+1是否符合要求            double[] minDis1 = new double[n + 1];  //用于保存当前minDis数组中值            for(int i = 1;i <= n;i++)                minDis1[i] = minDis[i];            for(int i = 1;i <= n;i++) {                if(minDis[i] > distance[i][current + 1]) {                    minDis[i] = distance[i][current + 1];                    judge = true;                }            }            tempAns[count + 1] = current + 1;            if(judge == true)  //邮局current + 1符合要求,选中个数加1继续搜索                dfs(count + 1, current + 1, minDis, tempAns);            dfs(count, current + 1, minDis1, tempAns); //直接舍弃邮局current+1,进行下一次搜索        }    }            public static void main(String[] args) {        Main test = new Main();        Scanner in = new Scanner(System.in);        n = in.nextInt();        m = in.nextInt();        k = in.nextInt();        test.init();        double[][] point = new double[n + 1][2];   //存放n个村庄的位置坐标        for(int i = 1;i <= n;i++) {            point[i][0] = in.nextDouble();   //村庄横坐标            point[i][1] = in.nextDouble();   //村庄纵坐标        }        for(int j = 1;j <= m;j++) {            double x = in.nextDouble();      //邮局横坐标            double y = in.nextDouble();      //邮局纵坐标            for(int i = 0;i <= n;i++)       //计算1~n村庄到邮局j的直线距离                distance[i][j] = Math.sqrt((point[i][0]-x)*(point[i][0]-x) +                         (point[i][1]-y)*(point[i][1]-y));        }        int[] tempAns = new int[k + 1];        double[] minDis = new double[n + 1]; //minDis[i]表示第i个村庄到已选中的邮局中的最小距离        for(int i = 1;i <= n;i++)            minDis[i] = Double.MAX_VALUE;//初始化第i个村庄到选中邮局中最小距离为最大值                test.dfs(0, 0, minDis,  tempAns);        for(int i = 1;i <= k;i++)            System.out.print(answer[i]+" ");    }}

 

 

 

 

 

 

 

参考资料:

   1.

 

转载于:https://www.cnblogs.com/liuzhen1995/p/6813461.html

你可能感兴趣的文章
Vim 常用快捷键
查看>>
lintcode :Count and Say 报数
查看>>
libeXosip2(3) -- SIP messages and call control API
查看>>
PHP-浏览器参数防注入检测函数
查看>>
面试技巧锦集
查看>>
PLSQL日期函数
查看>>
8 个最好的 jQuery 树形 Tree 插件
查看>>
jQuery的ajax跨域实现
查看>>
重温.NET下Assembly的加载过程
查看>>
前端读者 | 前端开发者调试面板vConsole
查看>>
PrimeNumber
查看>>
Array对象的方法实现(1)----Array.prototype.push和Array.prototype.concat(实现常规参数的功能)...
查看>>
UVA 10200 Prime Time 水
查看>>
Fidder模拟发送请求
查看>>
Linux基础
查看>>
js时间的操作,为了让cookie在当天24点过期~
查看>>
【USACO】干草金字塔
查看>>
编译Nginx, 并使用自签证书实现https访问
查看>>
整合VS2010和NUnit
查看>>
01Hibernate
查看>>