标签:sort 文件的 整数 next 测试数据 font style sys 表连接
目录
1<=U,V<=N<=50,N-1<=M<=1000,0<=W<=50。数据不超过5组。
本题主要考查Kruskal算法,其中的重点在于并查算法的应用,在寻找最小平方差的最小生成树时,需要枚举边权值的均值。
但是,依照这样的方法,在蓝桥练习系统中测评一直为50分,在网上找了一下其他网友写的C代码,提交也是50分,可能是蓝桥练习系统的后台测试数据有点问题,也有可能是本题枚举的精确度不够。
具体代码如下:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { public static int n, m; public static double minV; //输入所有边中权值最小的边 public static double maxV; //输入所有边中权值最大的边 public static int[] id; public static ArrayList<edge> map; public static ArrayList<Double> result = new ArrayList<Double>(); class MyComparator implements Comparator<edge> { public int compare(edge arg0, edge arg1) { if(arg0.w > arg1.w) return 1; else if(arg0.w < arg1.w) return -1; return 0; } } static class edge { public int a; //边的起点 public int b; //边的终点 public double v; //边的权值 public double w; //边权的方差值 public edge(int a, int b, double v) { this.a = a; this.b = b; this.v = v; this.w = 0; } } public void init() { minV = Double.MAX_VALUE; maxV = Double.MIN_VALUE; map = new ArrayList<edge>(); } public int find(int a) { int root = a; while(id[root] >= 0) { root = id[root]; } int k = a, i; while(k != root) { i = id[k]; id[k] = root; k = i; } return root; } public void union(int a, int b) { int rootA = find(a); int rootB = find(b); if(rootA == rootB) return; int num = id[rootA] + id[rootB]; if(id[rootA] < id[rootB]) { id[rootB] = rootA; id[rootA] = num; } else { id[rootA] = rootB; id[rootB] = num; } } public void getResult() { double avg = minV; double minResult = Double.MAX_VALUE; for(;avg <= maxV;avg = avg + 0.3) { //此处是解决本题的关键,即枚举最小生成树的边权的均值 for(int i = 0;i < map.size();i++) { double v = map.get(i).v - avg; map.get(i).w = v * v; } Collections.sort(map, new MyComparator()); id = new int[n + 1]; for(int i = 1;i <= n;i++) id[i] = -1; double sum = 0; double[] value = new double[n - 1]; int count = 0; for(int i = 0;i < map.size();i++) { int rootA = find(map.get(i).a); int rootB = find(map.get(i).b); if(rootA != rootB) { union(map.get(i).a, map.get(i).b); value[count++] = map.get(i).v; sum += map.get(i).v; if(count == n - 1) break; } } sum = sum / (n - 1); double temp = 0; for(int i = 0;i < value.length;i++) { temp = temp + (value[i] - sum) * (value[i] - sum); } temp = temp / (n - 1); if(minResult > temp) minResult = temp; } result.add(minResult); } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); while(true) { n = in.nextInt(); m = in.nextInt(); if(n == 0 || m == 0) break; test.init(); for(int i = 1;i <= m;i++) { int a = in.nextInt(); int b = in.nextInt(); double v = in.nextDouble(); map.add(new edge(a, b, v)); minV = Math.min(minV, v); maxV = Math.max(maxV, v); } test.getResult(); } for(int i = 0;i < result.size();i++) { System.out.print("Case "+(i+1)+": "); System.out.printf("%.2f", result.get(i)); System.out.println(); } } }
标签:sort 文件的 整数 next 测试数据 font style sys 表连接
原文地址:http://www.cnblogs.com/liuzhen1995/p/6786554.html