[伯俊]#10021 WateringtheFields



質問する


Due to a lack of rain, Farmer John wants to build an irrigation system to send water between his N fields (1 <= N <= 2000).
Each field i is described by a distinct point (xi, yi) in the 2D plane, with 0 <= xi, yi <= 1000. The cost of building a water pipe between two fields i and j is equal to the squared Euclidean distance between them:
(xi - xj)^2 + (yi - yj)^2
FJ would like to build a minimum-cost system of pipes so that all of his fields are linked together -- so that water in any field can follow a sequence of pipes to reach any other field.
Unfortunately, the contractor who is helping FJ install his irrigation system refuses to install any pipe unless its cost (squared Euclidean length) is at least C (1 <= C <= 1,000,000).
Please help FJ compute the minimum amount he will need pay to connect all his fields with a network of pipes.

入力

  • Line 1: The integers N and C.
  • Lines 2..1+N: Line i+1 contains the integers xi and yi.
  • しゅつりょく

  • Line 1: The minimum cost of a network of pipes connecting the fields, or -1 if no such network can be built.
  • 入力例1

    3 11
    0 2
    5 0
    4 3

    サンプル出力1

    46

    に答える


    この問題はMST(最小生成ツリー)問題であり,Kruskalアルゴリズムで解くことができる.問題は英語で、最後に出力条件がよく見えなかったので間違っていました.
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    import java.util.PriorityQueue;
    
    public class Main {
        static int[] parent;
    
        public static void main(String[] args) throws Exception{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] input = br.readLine().split(" ");
            int N = Integer.parseInt(input[0]);
            int min = Integer.parseInt(input[1]);
            PriorityQueue<Pair> pq = new PriorityQueue<>();
            int ans = 0;
            int cnt = 0;
            parent = new int[N];
            for(int i=0; i<N; i++)
                parent[i] = i;
    
            Pair[] arr= new Pair[N];
            for(int i=0; i<N; i++) {
                input = br.readLine().split(" ");
                arr[i] = new Pair(Integer.parseInt(input[0]), Integer.parseInt(input[1]), 0);
            }
    
            for(int i=0; i<N-1; i++) {
                Pair a = arr[i];
                for(int j=i+1; j<N; j++) {
                    Pair b = arr[j];
                    int cost = (int)(Math.pow(a.x-b.x , 2) + Math.pow(a.y-b.y, 2));
                    if(cost>=min)                         //최소 조건에 부합하는 통로만 큐에 
                        pq.add(new Pair(i, j, cost));
                }
            }
    
            while(!pq.isEmpty()) {
                Pair temp = pq.poll();
    
                int x = temp.x;
                int y = temp.y;
    
                if(find(x)==find(y)) continue;
    
                union(x, y);
                ans += temp.cost;
                cnt++;
            }
    
            if(cnt==N-1)
                System.out.println(ans);
            else
                System.out.println(-1);
        }
    
        public static void union(int x, int y) {
            x = find(x);
            y = find(y);
    
            if(x<y)
                parent[y] = x;
            else
                parent[x] = y;
        }
    
        public static int find(int x) {
            if(parent[x]==x)
                return x;
    
            return find(parent[x]);
        }
    
        public static class Pair implements Comparable<Pair>{
            int x;
            int y;
            int cost;
    
            public Pair(int x, int y, int cost) {
                this.x = x;
                this.y = y;
                this.cost = cost;
            }
    
            public int compareTo(Pair p) {
                return this.cost > p.cost ? 1 : -1;
            }
        }
    }