Mathlife
Mathlife의 학습 노트
Mathlife
전체 방문자
오늘
어제
  • 분류 전체보기
    • CS
      • 알고리즘
      • 자료구조
      • 운영체제
      • 네트워크
      • 데이터베이스
    • 프로그래밍 언어
      • Java
      • JavaScript
      • C·C++
      • Python
    • Backend
      • Spring
    • Frontend
      • HTML
      • CSS
    • Math
      • Linear Algebra
      • Calculus
    • AI
      • ML
      • DL
      • RL
    • Git

블로그 메뉴

  • 홈
  • 관리
  • 글쓰기
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Mathlife

Mathlife의 학습 노트

CS/알고리즘

MST

2022. 5. 13. 18:22

MST

스패닝 트리 : 그래프의 모든 정점을 포함하는 트리

최소 스패닝 트리 : 가중치의 합이 가장 작은 스패닝 트리

 

Kruscal

<원리>

1. 간선을 가중치 순으로 저장한다.

2. 간선을 순서대로 확인하면서 계속 추가한다. 사이클을 만드는 간선은 추가하지 않는다.

 

<구현>

1. 간선을 가중치 순으로 저장한다.

2. 간선을 순서대로 확인하면서 계속 추가한다.

- 두 정점이 같은 집합 안에 있다면 사이클을 만드는 간선이므로 무시한다

- 두 정점이 다른 집합 안에 있다면  union 연산을 수행하고 mst, mst_weight를 갱신한다.

 

def kruscal(adj): # adj : (weight, from, to) 의 배열
    mst = []
    mst_weight = 0
    
    adj.sort()
    uf = UnionFind(n)
    
    for w, x, y in adj:
        if uf.find(x) == uf.find(y): continue
        uf.union(x, y)
        mst.append((x, y))
        mst_weight += w
    
    return mst, mst_weight

 

시간 복잡도 : $O(|E|\log|E|)\ $ (간선의 정렬)

 

Prim

<원리>

1. MST를 단계적으로 확장한다

2. 현재까지 발견한 MST로부터 거리가 가장 짧은 정점을 추가한다

 

<구현>

1. 세팅

- check : 정점의 방문 여부

- parent : (임시) 부모 노드

- minDist : 현재까지 발견한 MST로부터의 거리

2. 정점을 V번 방문한다.

- 아직 방문하지 않은 정점 중 minDist가 최소인 정점을 x로 선택하고 방문한다.
- x의 부모 노드가 존재한다면(새로운 간선을 추가했다면) mst를 갱신한다.

- mst_weight를 갱신한다.
- x와 아직 방문하지 않은 nx 사이의 weight를 확인한다. 더 짧은 경로(MST - nx)를 발견한다면 nx의 parent, minDist를 갱신한다. 

 

def prim(adj):
    mst = []
    mst_weight = 0

    check = [False]*n # 방문 여부
    parent = [i for i in range(n)] # 부모 노드 저장
    INF = float('inf'); minDist = [INF]*n # MST로부터의 거리

    # 첫 번째 iteration에는 0이 선택 되도록 설정
    minDist[0] = 0
    for i in range(n):
        # MST로부터 거리가 가장 짧은 정점 선택
        x = INF
        for v in range(n):
            if not check[v] and (x == INF or minDist[v] < minDist[x]):
                x = v
        check[x] = True

        # MST 정보 갱신
        if x != parent[x]:
            mst.append((parent[x], x))
        mst_weight += minDist(x)

        # 방문하지 않은 인접 정점에 대한 정보 갱신
        for w, nx in adj[x]:
            if not check[nx] and w < minDist[nx]:
                parent[nx] = x
                minDist[nx] = w

    return mst, mst_weight

 

시간 복잡도 : $O(|V|^2)$

'CS > 알고리즘' 카테고리의 다른 글

가중치 있는 최단 경로 문제  (0) 2022.05.07
BBST / union-find  (0) 2022.05.06
DFS/BFS  (0) 2022.05.06
Merge Sort & Quick Sort (JAVA)  (0) 2022.04.20
LCS  (0) 2022.04.05
    'CS/알고리즘' 카테고리의 다른 글
    • 가중치 있는 최단 경로 문제
    • BBST / union-find
    • DFS/BFS
    • Merge Sort & Quick Sort (JAVA)
    Mathlife
    Mathlife

    티스토리툴바