티스토리 뷰
MST
방향이 없는 그래프에서 모든 정점을 연결하며 모든 간선의 합이 최소인 트리
Prim
다익스트라 알고리즘과 아주 유사함
출발 정점을 시작으로 이웃 정점들의 최소 간선을 갱신하면서 답을 찾아감
*시간복잡도: O(V^2 + E)
Java code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class Prim { int vertexNum; HashMap<Integer, Integer>[] graph; int prim(){ int[] minWeight = new int[vertexNum]; int[] parent = new int[vertexNum]; HashSet<Integer> Q = new HashSet<>(); Q.add(0); minWeight[0] = 0; parent[0] = 0; for(int i=1; i<vertexNum; i++){ Q.add(i); minWeight[i] = Integer.MAX_VALUE; parent[i] = -1; } int sumOfEdge = 0; while(!Q.isEmpty()){ Iterator<Integer> itr = Q.iterator(); int minVertex = 0; int min = Integer.MAX_VALUE; //아직 가지 않은 vertex 중 최소 찾기 while(itr.hasNext()){ int v = itr.next(); if(minWeight[v] < min){ minVertex = v; min = minWeight[v]; } } Q.remove(minVertex); sumOfEdge += min; for(int i : graph[minVertex].keySet()){ if(Q.contains(i) && minWeight[i] > graph[minVertex].get(i)){ minWeight[i] = graph[minVertex].get(i); parent[i] = minVertex; } } } return sumOfEdge; } } | cs |
Kruskal
모든 간선을 오름차순으로 정렬한 후 각 정점이 사이클을 이루지 않게 간선들을 선택함
사이클 여부를 확인하기 위해 Disjoint Set을 사용함
*시간복잡도: O(E*logE)
Java code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class Kruskal { UnionFind set; int vertexNum; HashMap<Integer, Integer>[] graph; static class Edge implements Comparable<Edge>{ int va; int vb; int weight; Edge(int a, int b, int w){ va = a; vb = b; weight = w; } @Override public int compareTo(Edge o) { return weight - o.weight; } } int kruskal(){ //그래프의 모든 간선 리스트 만들기 ArrayList<Edge> edges = new ArrayList<>(); for(int here=0; here<vertexNum; here++){ for(int there : graph[here].keySet()){ edges.add(new Edge(here, there, graph[here].get(there))); } } Collections.sort(edges); //간선 리스트 오름차순 정렬 set = new UnionFind(vertexNum); int sumOfEdge = 0; for(int i=0; i<edges.size(); i++){ int a = edges.get(i).va; int b = edges.get(i).vb; int weight = edges.get(i).weight; if(set.find(a) == set.find(b)) continue; //이미 같은 집합이면 무시 set.union(a, b); sumOfEdge += weight; } return sumOfEdge; } } | cs |
댓글