UVA 10369 - Arctic NetWork (求最小生成树)

题意:

  在南极有  N  个科研站,要把这些站用卫星和无线电连接起来,是的任意两个之间都能互相通信,如果其中任意的一个地方安装了卫星,那么就可以和其他安装卫星的互相通信,和距离没有关系,但是安装无线电 是需要费用D的,这个费用 D 为在安装无线电的地方中使用的无线电通信花费最大的那个值。现在有S个卫星可以提供给你安装,还有足够多的无线电设备,让你设计一个方案,使得D的费用最少。

思路:

  首先肯定会用到最小生成树。为了使得我们的D值最小那么我们应该给距离最长的 S - 1个路径的俩段安装无线电(因为 S个无线电可以连通S 个科研站,S个科研站有S- 1条路径)。这样的话设最小生成树一共有 K 条边,那么 第 K - S 条排好序的边就是我们要的答案。而 K = N - 1,所以我们最后要求的就是直接求最小生成树的 第 N - S 条边。

代码:

 

 1 import java.util.Scanner;
 2 import java.util.Comparator;
 3 import java.util.Arrays;
 4 import java.text.DecimalFormat;
 5 
 6 class Node{
 7     public int u, v, mark;
 8     public double w;
 9 }
10 class Points{
11     public double x;
12     public double y;
13 }
14 
15 class mycmp implements  Comparator<Node>{
16     public int compare(Node A, Node B){ 
17                 if(A.w == B.w) return 0;
18                 else if(A.w < B.w) return -1;
19                 else return 1;
20       }  
21 }
22 public class Main {
23     final static int MAXN = 250000 + 13;
24     final static int INF = 0x3f3f3f3f;
25     static int[] pre = new int[MAXN];
26     static Node[] map = new Node[MAXN];
27     static Points[] pit = new Points[MAXN];
28     public static void main(String[] args){
29         Scanner sc = new Scanner(System.in);
30         int T = sc.nextInt();
31         while(T != 0){
32             int S, P;
33             S = sc.nextInt();
34             P = sc.nextInt();
35             mst(P);
36             for(int i = 1; i <= P; i++){
37                 pit[i] = new Points();
38                 pit[i].x = sc.nextInt();
39                 pit[i].y = sc.nextInt();
40             }
41             int len = 1;
42             for(int i = 1; i < P; i++){
43                 for(int j = i + 1; j <= P; j++){
44                     map[len] = new Node();
45                     map[len].u = i;
46                     map[len].v = j;
47                     map[len].w = dist(pit[i], pit[j]);
48                     len++;
49                 }
50             }
51             Arrays.sort(map, 1, len,  new mycmp());
52             int k = P - S;  //第 K 条边就是答案
53             double ans = ksu(P, len, k);
54             DecimalFormat df = new DecimalFormat("0.00");
55             String db = df.format(ans);
56             System.out.println(db);
57             T--;
58         }
59         sc.close();
60     }
61     public static double dist(Points a, Points b){
62         return Math.sqrt( (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) );
63     }
64     public static double ksu(int N, int M, int k){ 
65         int cnt = 0;
66         double ans = map[M - 1].w;//初始化为最大的那条边
67         for(int i = 1; i < M; i++){
68             int fu = Find(map[i].u);
69             int fv = Find(map[i].v);
70             if(fu != fv){
71                 cnt++;
72                 if(cnt == k){ //找到第K条边
73                     ans = map[i].w;
74                 }
75                 pre[fv] = fu;
76                 map[i].mark = 1;   
77             }
78         }
79         return ans;
80     }
81     public static int Find(int x){
82         return x == pre[x] ? x : (pre[x] = Find(pre[x]));
83     }
84     public static void mst(int N){
85         for(int i = 1; i <= N; i++){
86             pre[i] = i;
87         }
88     }
89 }

 

 


posted @ 2016-04-03 12:50  vrsashly  阅读(213)  评论(0编辑  收藏  举报