문제
풀이
- `Union-Find` 알고리즘을 사용한다.
- 파티에 참가한 사람 별로 부모노드를 설정하여 서로간의 부모노드를 비교하여 같은 집합에 속해있는지 확인한다.
- 진실을 아는 집합 내의 사람이 파티에 속해있는 파티에서는 거짓말을 할 수 없다.
코드
#include <iostream>
#include <vector>
using namespace std;
vector<int> knowns;
vector<int> parties[51];
int parent[51];
// 노드의 부모 노드를 반환
int getParent(int n)
{
if (parent[n] == n)
{
return n;
}
return getParent(parent[n]);
}
// 노드의 부모를 서로 연결하여 같은 집합에 속하게 한다.
void Union(int n1, int n2)
{
n1 = getParent(n1);
n2 = getParent(n2);
parent[n1] = n2;
}
int main()
{
int N;
int M;
int knowns_num;
int answer;
cin >> N >> M;
cin >> knowns_num;
for (int i = 0; i < knowns_num; ++i)
{
int temp;
cin >> temp;
knowns.push_back(temp);
}
for (int i = 0; i < N; ++i)
{
parent[i] = i;
}
for (int i = 0; i < M; ++i)
{
int num;
cin >> num;
int prev;
int current;
for (int j = 0; j < num; ++j)
{
if (j < 1)
{
cin >> current;
}
else
{
// 같은 파티에 참여한 사람끼리 같은 집합에 속하도록 한다.
prev = current;
cin >> current;
Union(prev, current);
}
parties[i].push_back(current);
}
}
answer = M;
for (vector<int> party : parties)
{
bool flag = false;
for (int person : party)
{
if (flag)
{
break;
}
for (int known : knowns)
{
// 파티에 참가한 사람들 중 한명이라도 사실을 아는 집합에 속해있다면 지민이는 참여할 수 없다.
if (getParent(person) == getParent(known))
{
flag = true;
break;
}
}
}
if (flag)
{
answer--;
}
}
cout << answer;
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준][C++] 1987: 알파벳 (0) | 2023.09.25 |
---|---|
[백준][C++] 1504: 특정한 최단 경로 (0) | 2023.09.24 |
[백준][C++] 17070: 파이프 옮기기1 (0) | 2023.09.22 |
[백준][C++] 11444: 피보나치 수 6 (0) | 2023.09.21 |
[백준][C++] 1918: 후위 표기식 (0) | 2023.09.20 |