CPU消耗 < 3000ms
-------------------------------------------
思路:用死办法,遍历每种结果取最小值。
import java.util.Scanner; import java.util.ArrayList; import java.util.Arrays; import static java.lang.Math.*; public class BlueBridgeExcercise5{ private static int[] combiArr; //临时数组 private static double[][] distance; //所有距离数据 private static ArrayList<int[]> combiList = new ArrayList<int[]>(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //村民的户数 int m = sc.nextInt(); //备选邮局数 int k = sc.nextInt(); //要建邮局数 int[] nArrX = new int[n]; //村民家坐标 int[] nArrY = new int[n]; int[] mArrX = new int[m]; //备选邮局坐标 int[] mArrY = new int[m]; for(int i = 0; i < n; i++){ //输入坐标 nArrX[i] = sc.nextInt(); nArrY[i] = sc.nextInt(); } for(int i = 0; i < m; i++){ mArrX[i] = sc.nextInt(); mArrY[i] = sc.nextInt(); } distance = new double[n][m]; //村民家与备选邮局间的距离 for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ distance[i][j] = sqrt(pow(nArrX[i]-mArrX[j], 2) + pow(nArrY[i]-mArrY[j], 2)); } } combiArr = new int[k]; combination(m-1, k, 0); int[] best = findLeast(n); for(int i = best.length-1; i >= 0; i--){ System.out.print((best[i]+1) + " ");//运算时编号为0~m-1,加上为题设 } } //找出所有组合 private static void combination(int mMax, int k, int kMax){ if(k==1){ for(int i = mMax; i >= 0; i--){ combiArr[kMax] = i; int[] temp = Arrays.copyOf(combiArr, combiArr.length);//不能直接add原数组 combiList.add(temp); } } else{ for(int i = mMax; i >= k-1; i--){ combiArr[kMax] = i; combination(i-1, k-1, kMax+1); } } } //找出最短路径的组合 private static int[] findLeast(int n){ double sumLength = 0; int[] best = combiList.get(0); int[] temp; double[] tempEvery = new double[best.length]; for(int i = 0; i < n; i++){ for(int k = 0; k < best.length; k++){ tempEvery[k] = distance[i][best[k]]; } Arrays.sort(tempEvery); sumLength += tempEvery[0];//加上到备选邮局的最小距离 } double shortest = sumLength; for(int j = 1; j < combiList.size(); j++){ temp = combiList.get(j); sumLength = 0; for(int i = 0; i < n; i++){ for(int k = 0; k < temp.length; k++){ tempEvery[k] = distance[i][temp[k]]; } Arrays.sort(tempEvery); sumLength += tempEvery[0]; } if(sumLength < shortest){ shortest = sumLength; best = temp; } } return best; } }