很快就想到了总边长减最大生成树,但是还是wa,没想到是java比较器强转导致的精度问题,×10后还是wa,精度不够,又×1000000终于够了。还有就是par是复制粘贴的忘改了,re了一次。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class AOJ_2224 {
static class zhuang{
int i,x,y;
}
static zhuang z[]=new zhuang[10005];
static class edge{
int from,to;
double cost;
public int getFrom() {
return from;
}
public int getTo() {
return to;
}
public double getCost() {
return cost;
}
public edge(int from, int to, double cost) {
this.from = from;
this.to = to;
this.cost = cost;
}
}
static edge es[]=new edge[50000];
static int n,m;
static double INF=-9999999.0,count;
public static void main(String[] args) {
for (int i = 0; i < z.length; i++) {
z[i]=new zhuang();
}
for (int i = 0; i < es.length; i++) {
es[i]=new edge(0,0,INF);
}
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
for (int i = 1; i <= n; i++) {
z[i].i=i;
z[i].x=sc.nextInt();
z[i].y=sc.nextInt();
}
for (int i = 0; i < m; i++) {
int p=sc.nextInt();
int q=sc.nextInt();
es[i].from=p;
es[i].to=q;
es[i].cost=Math.sqrt(Math.pow((z[es[i].from].x-z[es[i].to].x),2)+Math.pow((z[es[i].from].y-z[es[i].to].y),2));
count+=es[i].cost;
}
double ans=kruskal();
ans=count-ans;
System.out.println(String.format("%.3f",ans));
}
static double kruskal(){
Comparator<edge> cmp=new Comparator<edge>() {
@Override
public int compare(edge o1, edge o2) {
return (int) (o2.getCost()*100000-o1.getCost()*100000);
}
};
Arrays.sort(es,cmp);
init(n);
double res=0.0;
for (int i = 0; i < m; i++) {
edge e=es[i];
if(!same(e.from,e.to)){
unite(e.from,e.to);
res+=e.cost;
}
}
return res;
}
static int[] par=new int[10050];
static int[] rank=new int[10050];
static void init(int n){
for (int i = 0; i < n; i++) {
par[i]=i;
rank[i]=0;
}
}
static int find(int x){
if(par[x]==x){
return x;
}else{
return par[x]=find(par[x]);
}
}
static void unite(int x,int y){
x=find(x);
y=find(y);
if(x==y)return;
if(rank[x]<rank[y]){
par[x]=y;
}else{
par[y]=x;
if(rank[x]==rank[y])rank[x]++;
}
}
static boolean same(int x,int y){
return find(x)==find(y);
}
}