import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
float[][] dis = new float[21][21];
int[] x = new int[n + 1];
int[] y = new int[n + 1];
//这里从一开始,因为还有个原点
for (int i = 1; i <= n; i++) {
int row = scanner.nextInt();
int col = scanner.nextInt();
x[i] = row;
y[i] = col;
}
// 要计算任意两点的距离公式 权值,需要注意还有到原点的距离
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dis[i][j] = (float) Math.sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
}
}
float[][] dp = new float[1 << 16][21];
// 初始化位最大值
for (int i = 0; i < 1 << 16; i++) {
Arrays.fill(dp[i], Float.MAX_VALUE);
}
dp[1][0] = 0; //开始集合只有一个
n = n + 1; //细节,因为加上了原点这个点
for (int S = 1; S < (1 << n); S++) { // 集合扩张
for (int j = 0; j < n; j++) { // 枚举j
if (((S >> j) & 1) != 0) {
for (int k = 0; k < n; k++) {
// 集合去除j,(S ^ (1 << j))得到集合S-j,相同时为0,再看看枚举的k在不在S-j中
if (((S ^ (1 << j)) >> k & 1) != 0) {
dp[S][j] = Math.min(dp[S][j], dp[S ^ (1 << j)][k] + dis[k][j]);
}
}
}
}
}
float ans = Float.MAX_VALUE;
for (int j = 0; j < n; j++) {
ans = Math.min(dp[(1 << n) - 1][j], ans);
}
System.out.printf("%.2f", ans);
}
}
求助大佬,提交有4个点re了!!! 看了一小时每发现问题