algorithm/그래프

BOJ - 1647 도시분할계획

아르비스 2019. 9. 3. 12:40

https://www.acmicpc.net/problem/1647

 

1647번: 도시 분할 계획

첫째 줄에 집의 개수N, 길의 개수M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번 집과 B번 집을 연결하는 길의 유지비가 C (1 ≤ C ≤ 1,000)라는 뜻이다.

www.acmicpc.net

최소 스패닝 트리를 구해주면 된다.

 

주의할 점은 하나인 마을을 두개로 나누고 싶다고 하고 있기 때문에 " N-2개" 의 간선만 연결해주면 된다.

위 N-2 가 핵심임.. 문제 이해를 못해서. 한참 고심함.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class BOJ1647 {
    static int N, M;
    static Edge[] edges;
    static DJS djs;
    static class Edge implements Comparable<Edge> {
        int s, e, v;
        Edge(int s, int e, int v) {
            this.s = s;
            this.e = e;
            this.v = v;
        }

        @Override
        public int compareTo(Edge o) {
            return this.v - o.v;
        }
    }
    static class DJS {
        int[] mom;
        DJS(int n) {
            mom = new int[n+1];
            for (int i = 1; i <= n  ; i++) mom[i]=i;
        }
        public int find(int n) {
            if(n==mom[n]) return n;
            return mom[n] = find(mom[n]);
        }
        public boolean union(int a, int b) {
            a = find(a);
            b = find(b);
            if(a==b) return false;
            mom[b] = a;
            return true;
        }
    }

    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream("res/input_boj1647.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine().trim(), " ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        djs = new DJS(N);
        edges = new Edge[M];
        int a, b, c;
        for (int i = 0; i < M ; i++) {
            st = new StringTokenizer(br.readLine().trim(), " ");
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());
            edges[i] = new Edge(a, b, c);
        }

        Arrays.sort(edges);

        Edge ed;
        long result = 0;
        int cnt = 0;
        for (int i = 0; i < M ; i++) {
            ed = edges[i];
            if(djs.union(ed.s, ed.e)){
                result += ed.v;
                cnt ++;
                if(cnt>= (N-2)) break;
            }
        }

        System.out.println(result);
    }
}