시간 제한 2초, 골드 IV, 백준 1043번
지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게 과장해서 말한다. 당연히 과장해서 이야기하는 것이 훨씬 더 재미있기 때문에, 되도록이면 과장해서 이야기하려고 한다. 하지만, 지민이는 거짓말쟁이로 알려지기는 싫어한다. 문제는 몇몇 사람들은 그 이야기의 진실을 안다는 것이다. 따라서 이런 사람들이 파티에 왔을 때는, 지민이는 진실을 이야기할 수 밖에 없다. 당연히, 어떤 사람이 어떤 파티에서는 진실을 듣고, 또다른 파티에서는 과장된 이야기를 들었을 때도 지민이는 거짓말쟁이로 알려지게 된다. 지민이는 이런 일을 모두 피해야 한다.
사람의 수 N이 주어진다. 그리고 그 이야기의 진실을 아는 사람이 주어진다. 그리고 각 파티에 오는 사람들의 번호가 주어진다. 지민이는 모든 파티에 참가해야 한다. 이때, 지민이가 거짓말쟁이로 알려지지 않으면서, 과장된 이야기를 할 수 있는 파티 개수의 최댓값을 구하는 프로그램을 작성하시오.
첫째 줄에 사람의 수 N과 파티의 수 M이 주어진다.
둘째 줄에는 이야기의 진실을 아는 사람의 수와 번호가 주어진다. 진실을 아는 사람의 수가 먼저 주어지고 그 개수만큼 사람들의 번호가 주어진다. 사람들의 번호는 1부터 N까지의 수로 주어진다.
셋째 줄부터 M개의 줄에는 각 파티마다 오는 사람의 수와 번호가 같은 방식으로 주어진다.
N, M은 50 이하의 자연수이고, 진실을 아는 사람의 수는 0 이상 50 이하의 정수, 각 파티마다 오는 사람의 수는 1 이상 50 이하의 정수이다.4 3 # 사람 수, 파티 수 0 # 진실을 아는 사람 정보 2 1 2 # 파티 정보 1 3 3 2 3 4
첫째 줄에 문제의 정답을 출력한다.
3
N(사람 수) M(파티 개수)
trueP(진실을 아는 사람 데이터)
T(진실을 아는 사람 수)
party(파티 데이터)
# find 연산
find(a):
a가 대표 노드면 리턴
아니면 a의 대표 노드 값을 find(parent[a]) 값으로 저장 - 재귀 함수 형태
# union 연산
union(a, b):
a와 b의 대표 노드 찾기
두 원소의 대표 노드끼리 연결
# checkSame -> 두 원소가 같은 집합인지 확인
checkSame(a, b):
a와 b의 대표 노드 찾기
두 대표 노드가 같으면 true
아니면 false return
파티 데이터 저장
for N만큼 반복:
대표 노드를 자기 자신으로 초기화
for M만큼 반복:
firstPeople(i번째 파티의 1번째 사람)
for j를 i번째 파티의 사람 수만큼 반복:
union(firstPeople, j) # 각 파티에 참여한 사람들을 1개의 그룹으로 만들기
for M만큼 반복:
firstPeople(i번째 파티의 사람)
for j -> 진실을 아는 사람들의 수만큼 반복:
# 각 파티의 대표 노드와 진실을 아는 사람들의 대표 노드가 같다면 과장할 수 없음
find(firstPeople), find(trueP[j]) 비교
모두 다른 경우 결괏값 1 증가
결괏값 출력
N, M = map(int, input().split())
trueP = list(map(int, input().split())) # 진실을 아는 사람 저장
T = trueP[0]
del trueP[0]
result = 0
party = [[] for _ in range(M)]
def find(a): # find 연산
if a == parent[a]:
return a
else:
parent[a] = find(parent[a]) # 재귀 형태로 구현 -> 경로 압축 부분
return parent[a]
def union(a, b): # union 연산 대표 노드끼리 합치기
a = find(a)
b = find(b)
if a != b:
parent[b] = a
def checkSame(a, b): # 두 원소가 같은 집합에 속해 있는지 확인하는 함수
a = find(a)
b = find(b)
if a == b:
return True
return False
for i in range(M):
party[i] = list(map(int, input().split())) # 파티 데이터 저장
del party[i][0] # 맨 하단에 설명 적어둠!
parent = [0] * (N + 1)
for i in range(N + 1): # 대표 노드를 자기 자신으로 초기화
parent[i] = i
for i in range(M): # 각 파티에 참여한 사람들을 1개의 그룹으로 만들기
firstPeople = party[i][0]
for j in range(1, len(party[i])):
union(firstPeople, party[i][j])
# 각 파티의 대표 노드와 진실을 아는 사람들의 대표 노드가 같다면 과장할 수 없음
for i in range(M):
isPossible = True
cur = party[i][0]
for j in range(len(trueP)):
if find(cur) == find(trueP[j]):
isPossible = False
break
if isPossible:
result += 1 # 모두 다르면 결괏값 1 증가
print(result)