按照模板写了一遍Prim算法,不知道为什么永远只能AC第一个。
后来修改了求边权的sqrt,把两个参数强行转换为double后就全AC了(狗头问号)
import java.util.*;
//import java.math.BigDecimal;
//import java.math.RoundingMode;
public class 最小生成树_Prim2 {
static int x[];//x坐标
static int y[]; //y坐标
static double ans=0;
static boolean vis[];
static double []dis;
// static List<Integer> ll=new ArrayList<>();
static double getV(int x1,int y1,int x2,int y2) {
//此乃关键之处!!!
double val=Math.sqrt((double)(x1-x2)*(x1-x2)+(double)(y1-y2)*(y1-y2));//就是这里!!!
return val;
}
public static void main(String []args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();//城市数量
x=new int[n];
y=new int[n];
vis=new boolean[n];
dis=new double[n];
for(int i=0;i<n;i++) {
x[i]=scanner.nextInt();
y[i]=scanner.nextInt();
dis[i]=Double.MAX_VALUE;
}
Prim(0);
// BigDecimal bd=new BigDecimal(ans).setScale(2, RoundingMode.HALF_UP);
//
// System.out.println(bd);
System.out.printf("%.2f",ans);
}
static void Prim(int start) {
int n=x.length;
dis[0]=0;
vis[0]=true;
int cur; //每次的当前节点
double minn; //当前节点延伸出去的最短边权
for(int i=0;i<n;i++) {
cur=0; //第一轮默认最初节点
minn=Double.MAX_VALUE;
for(int j=0;j<n;j++) {
if(dis[j]<minn&&!vis[j]) {
cur=j;
minn=dis[j];
}
}
ans+=dis[cur]; //加上当前节点
vis[cur]=true;
//再重新计算其他边
for(int j=0;j<n;j++) {
if (!vis[j]) {
double d = getV(x[cur], y[cur], x[j], y[j]);
dis[j] = Math.min(dis[j], d);
}
}
}
}
}