728x90
문제 요약
진실을 모르는 파티의 최대 개수 출력
접근
1. union find
union find로 풀어야될거같았다.
입력받을 때 같은 파티에 있는 사람들끼리 union 시킨다.
for (size_t i = 1; i < M + 1; i++)
{
int length;
cin >> length;
party[i][0] = length;
for (size_t j = 1; j < length + 1; j++)
{
cin >> party[i][j];
if (j == 1) continue;
unionAB(party[i][j-1], party[i][j]);
}
}
- 처음엔 하나를 고정시켜놓고 union 했는데 잘 안풀렸다.
- 이웃한 사람끼리 union을 진행했다.
입력이 끝난 이후에 모든 파티를 순회하면서 find로 진실을 모르는 파티가 있는지 확인한다.
void check()
{
for (size_t i = 1; i < M + 1; i++)
{
int length = party[i][0];
int break_chk = 0;
for (size_t j = 1; j < length + 1; j++)
{
if (knowTruth[find(party[i][j])])
{
break_chk = 1;
break;
}
}
if (!break_chk)
{
answer += 1;
}
}
}
알고리즘
- find본인을 가리키고 있으면 본인의 번호를, 본인이 아닌 번호를 가리키고 있으면 최상위 노드를 반환한다.
int find(int A) { if (p[A] == A) return A; p[A] = find(p[A]); return p[A]; }
- union두 노드가 가리키고 있는 최상위 노드로 업데이트하고, 둘중에 하나가 진실을 알고있으면 둘다 true로 갱신한다.
void unionAB(int A, int B) { A = find(A); B = find(B); p[B] = A; if (knowTruth[A] || knowTruth[B]) { knowTruth[A] = 1; knowTruth[B] = 1; } }
전체 코드
#include <iostream>
using namespace std;
#define MAX 51
int N, M, numTruth, answer;
int p[MAX], knowTruth[MAX];
int party[MAX][MAX];
int find(int A)
{
if (p[A] == A)
return A;
p[A] = find(p[A]);
return p[A];
}
void unionAB(int A, int B)
{
A = find(A);
B = find(B);
p[B] = A;
if (knowTruth[A] || knowTruth[B])
{
knowTruth[A] = 1;
knowTruth[B] = 1;
}
}
void init()
{
cin >> N >> M;
for (size_t i = 1; i < N + 1; i++)
{
p[i] = i;
}
cin >> numTruth;
for (size_t i = 0; i < numTruth; i++)
{
int num;
cin >> num;
knowTruth[num] = 1;
}
for (size_t i = 1; i < M + 1; i++)
{
int length;
cin >> length;
party[i][0] = length;
for (size_t j = 1; j < length + 1; j++)
{
cin >> party[i][j];
if (j == 1) continue;
unionAB(party[i][j-1], party[i][j]);
}
}
}
void check()
{
for (size_t i = 1; i < M + 1; i++)
{
int length = party[i][0];
int break_chk = 0;
for (size_t j = 1; j < length + 1; j++)
{
if (knowTruth[find(party[i][j])])
{
break_chk = 1;
break;
}
}
if (!break_chk)
{
answer += 1;
}
}
}
int main()
{
init();
check();
cout << answer << endl;
return 0;
}
'STUDY > Algorithm' 카테고리의 다른 글
[백준]17070 파이프 옮기기 1, C++ (0) | 2022.10.12 |
---|---|
[백준] 1167 트리의 지름, C++ (0) | 2022.10.12 |
[백준] 2812 크게 만들기, C++ (1) | 2022.10.11 |
[백준] 2493 탑 C++ (0) | 2022.10.11 |
[프로그래머스] 모음사전, C++ (1) | 2022.10.11 |