티스토리 뷰

인프런 - it 취업을 위한 알고리즘 문제풀이 (with C/C++) : 코딩테스트 대비 강의를 바탕으로 공부한 내용입니다.

문제는 비공개

 

풀이 

- 크루스칼 알고리즘: 최소신장트리를 구성하는 알고리즘으로 k개의 노드에 K-1개의 간선을 선택한다.

- 가장 적은 비용으로 트리를 구성하는데 가중치를 오름차순 정렬한 후 가중치가 낮은 간선을 먼저 선택한다.

- for문을 돌면서 v1, v2의 집합이 같은지 find로 확인 후 같지 않으면 res에 가중치를 더하고 두 집합을 하나로 union한다.

- union : find로 a,b의 집합을 찾고 이 집합이 서로 다를시에 unf[a]=b함으로써 하나로 합쳐준다.

- 앞서 푼 문제와 union&find로 같은 알고리즘을 사용한다

 

 

#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
int unf[10001];

//78. 원더랜드(Kruskal MST 알고리즘)
//최소비용 트리

struct Edge{
    int v1;
    int v2;
    int val;
    Edge(int a, int b, int c){
        v1=a;
        v2=b;
        val=c;
    }
    bool operator<(const Edge &b) const{
        return val<b.val;
    }
};

int Find(int v){
    if(v==unf[v]) return v;
    else return unf[v]=Find(unf[v]);
}

void Union(int a, int b){
    a=Find(a);
    b=Find(b);
    if(a!=b) unf[a]=b;
}

int main(){
    vector<Edge> Ed;
    int i, n, m, a, b, c, res=0;
    scanf("%d %d", &n, &m);
    for(i=1;i<=n;i++){
        unf[i]=i;
    }
    for(i=1;i<=m;i++){
        scanf("%d %d %d", &a, &b, &c);
        Ed.push_back(Edge(a, b, c));
    }
    sort(Ed.begin(), Ed.end()); //가중치 오름차순 정렬
    for(i=0;i<m;i++){
        //두개 정점 Find
        int fa=Find(Ed[i].v1);
        int fb=Find(Ed[i].v2);
        if(fa!=fb){
            //다른 집합이면 가중치를 더하고
            res+=Ed[i].val;
            //Union한다
            Union(Ed[i].v1, Ed[i].v2);
        }
    }
    printf("%d\n", res);
    return 0;
}


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

82. 순열구하기 [DFS]  (0) 2021.02.17
79. 원더랜드 [Prim 알고리즘 이용]  (0) 2021.02.15
77. 친구인가  (0) 2021.02.09
프로그래머스 - 네트워크  (0) 2021.02.08
76. 이항계수 [메모이제이션]  (0) 2021.02.05
최근에 올라온 글
Total
Today
Yesterday