PS/백준

[백준 - 16562] 친구비

이세형 2020. 11. 22. 14:54

- 문제설명

 

 

- 풀이코드

 

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<iostream>
#include<vector>
#include<set>
 
using namespace std;
 
int find(vector<int> &friends,int v){
    if(friends[v]==v) return v;
    else return friends[v] = find(friends,friends[v]);
}
 
void my_union(vector<int> &friends, int v,int w){
    int v_p = find(friends,v);
    int w_p = find(friends,w);
    if(v_p!=w_p) friends[v_p] = w_p;
}
 
 
int main(void){
 
    int n,m,k;
    int total = 0;
    cin >> n >> m >> k;
 
    vector<int> friends(n+1,0);
    vector<int> costs(n+1,0);
    vector<int> min_costs(n+1,INT32_MAX);
    for(int i=1;i<=n;i++){
        friends[i]=i;
        cin >> costs[i];
    }
    for(int i=0;i<m;i++){
        int v,w;
        cin >> v >> w;
        my_union(friends,v,w);
    }
 
    for(int i=1;i<=n;i++){
        friends[i] = find(friends,i);
    }
 
    set<int> friend_p;
    for(int i=1;i<=n;i++){
        friend_p.insert(friends[i]);
    }
 
    for(auto p : friend_p){
        int min = INT32_MAX;
        for(int i=1;i<=n;i++){
            if(friends[i]==p){
                min = min < costs[i] ? min : costs[i];
            }
        }
        total += min;
    }
 
 
    if(total>k) cout << "Oh no";
    else cout << total;
 
    return 0;
}
cs

 

- 시간복잡도

O(nlogn) - 셋을 사용했기에 최악의 경우시 nlogn

 

- 남의 풀이와 비교

union-find로 친구 그룹을 만들고 set을 활용해서해당 그룹에서 제일 친구비가 낮은 친구를 선택하는 방법으로 풀었다.

다른 사람의 풀이를 보니 set을 사용하지 않고 O(n)만에 푼 풀이법들이 있었다. union-find로 그룹을 나눈 뒤 해당 그룹들을 효과적으로 다루는 문제들을 더 풀어봐야겠다.

 

- Reference

www.acmicpc.net/problem/16562