코딩 공부/백준

[백준][C++] 1043 거짓말

김 정 환 2021. 4. 21. 21:11
반응형

www.acmicpc.net/problem/1043

 

1043번: 거짓말

지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게

www.acmicpc.net

 

 

 

알고리즘 종류

자료구조

부분 집합

 

 

사고 과정

문제에서 제시된 예시를 가지고 손으로 풀이를 해보고 있었습니다. 파티에서 참가하는 사람들을 하나로 묶고 그중에서 한 명이 진실을 알면 파티에 갈 수 없다고 생각했습니다. 즉, 부분 집합을 만들면 될 것 같았습니다.

 

1. 인접 리스트(party)로 파티에 들어갈 사람들을 담습니다. 그리고 for문으로 파티를 돌면서 부분 집합을 만듭니다.

 

2. 파티를 for문으로 돌면서 부모(대표)를 가져옵니다. 그리고 for문으로 진실을 아는 사람들을 돌면서 파티의 대표와 진실을 아는 사람의 부모가 같은 지 확인 합니다.

 

3. '진실을 아는 사람의 부모'와 '파티의 부모'가 같다면, 그 파티에는 진실을 아는 사람이 포함되어 있는 것이므로 그 파티에 갈 수 없습니다.

 

 

 

구현(C++)

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <vector>
 
using namespace std;
 
int n, m;
int ans;
 
int parents[51];
 
vector<int> party[51];
 
 
int get_parent(int a){
    if(parents[a] == a) return a;
    return parents[a] = get_parent(parents[a]);
}
 
 
void union_parents(int a, int b){
    a = get_parent(a);
    b = get_parent(b);
    
    if(a > b) parents[b] = a;
    else parents[a] = b;
}
 
int main(void){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n >> m;
    ans = m;
    
    int k, v;
    vector<int > tmp;
    
    cin >> k;
    for(int i=0; i<k; i++){
        cin >> v;
        tmp.push_back(v);
    }
    
    for(int i=0; i<m; i++){
        cin >> k;
        for(int j=0; j<k; j++){
            cin >> v;
            party[i].push_back(v);
        }
    }
    
    for(int i=0; i<=n; i++) parents[i]= i;
    
    // 파티의 사람들을 부분 집합으로 묶기
    for(int i=0; i<m; i++){
        if(party[i].size() == 0continue;
        
        int p = party[i][0];
        for(int j=0; j<party[i].size(); j++){
            union_parents(p, party[i][j]);
        }
    }
    
    // 파티를 돌면서 파티의 부모(대표)와 진실을 아는 사람이 같다면, 그 파티는 갈 수 없다. 
    for(int i=0; i<m; i++){
        if(party[i].size() == 0continue;
        
        bool flag = true;
        
        int node1 = get_parent(party[i][0]);
        for(int j=0; j<tmp.size(); j++){
            int node2 = get_parent(tmp[j]);
            
            if(node1 == node2){
                flag = false;
                break;
            }
        }
        if(flag == false) ans--;
    }
    
    cout << ans << endl;
}
cs

 

 

 

시행착오

반응형

'코딩 공부 > 백준' 카테고리의 다른 글

[백준][C++] 1976 여행 가자  (0) 2021.04.22
[백준][C++] 17298 오큰수  (0) 2021.04.22
[백준][C++] 7662 이중 우선순위 큐  (0) 2021.04.21
[백준][C++] 11000 강의실 배정  (0) 2021.04.21
[백준][C++] 1918 후위 표기식  (0) 2021.04.20