일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- CCW 알고리즘
- 에라토스테네스의 체
- 다익스트라
- 비트마스킹
- Bitmasking
- 이진 탐색
- Two Pointers
- deque
- 백준
- 에라토스테네스
- 외적
- 재귀
- 비트연산
- Python
- 투 포인터
- 딕셔너리
- 너비우선탐색
- DP
- BOJ
- CCW알고리즘
- dijkstra algorithm
- 큐
- 소수
- binary search
- ccw
- 위상정렬
- BFS
- Algorithm
- 알고리즘
- recursion
- Today
- Total
꾸꾸리
[BOJ/Python] 1043_거짓말 본문
문제 출처:https://www.acmicpc.net/problem/1043
1043번: 거짓말
지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게
www.acmicpc.net
문제
지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게 과장해서 말한다. 당연히 과장해서 이야기하는 것이 훨씬 더 재미있기 때문에, 되도록이면 과장해서 이야기하려고 한다. 하지만, 지민이는 거짓말쟁이로 알려지기는 싫어한다. 문제는 몇몇 사람들은 그 이야기의 진실을 안다는 것이다. 따라서 이런 사람들이 파티에 왔을 때는, 지민이는 진실을 이야기할 수 밖에 없다. 당연히, 어떤 사람이 어떤 파티에서는 진실을 듣고, 또다른 파티에서는 과장된 이야기를 들었을 때도 지민이는 거짓말쟁이로 알려지게 된다. 지민이는 이런 일을 모두 피해야 한다.
사람의 수 N이 주어진다. 그리고 그 이야기의 진실을 아는 사람이 주어진다. 그리고 각 파티에 오는 사람들의 번호가 주어진다. 지민이는 모든 파티에 참가해야 한다. 이때, 지민이가 거짓말쟁이로 알려지지 않으면서, 과장된 이야기를 할 수 있는 파티 개수의 최댓값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 사람의 수 N과 파티의 수 M이 주어진다.
둘째 줄에는 이야기의 진실을 아는 사람의 수와 번호가 주어진다. 진실을 아는 사람의 수가 먼저 주어지고 그 개수만큼 사람들의 번호가 주어진다. 사람들의 번호는 1부터 N까지의 수로 주어진다.
셋째 줄부터 M개의 줄에는 각 파티마다 오는 사람의 수와 번호가 같은 방식으로 주어진다.
N, M은 50 이하의 자연수이고, 진실을 아는 사람의 수는 0 이상 50 이하의 정수, 각 파티마다 오는 사람의 수는 1 이상 50 이하의 정수이다.
출력
첫째 줄에 문제의 정답을 출력한다.
예제 입력 1
4 3
0
2 1 2
1 3
3 2 3 4
예제 출력 1
3
예제 입력 2
4 1
1 1
4 1 2 3 4
예제 출력 2
0
예제 입력 3
4 1
0
4 1 2 3 4
예제 출력 3
1
예제 입력 4
4 5
1 1
1 1
1 2
1 3
1 4
2 4 1
예제 출력 4
2
예제 입력 5
10 9
4 1 2 3 4
2 1 5
2 2 6
1 7
1 8
2 7 8
1 9
1 10
2 3 10
1 4
예제 출력 5
4
예제 입력 6
8 5
3 1 2 7
2 3 4
1 5
2 5 6
2 6 8
1 8
예제 출력 6
5
예제 입력 7
3 4
1 3
1 1
1 2
2 1 2
3 1 2 3
예제 출력 7
0
풀이
M개의 파티 중에서 거짓말을 할 수 있는 파티의 수를 구하는 문제이다.
- 진실은 아는 사람이 파티에 있다면 그 파티에서는 거짓말을 할 수 없다.
- 그렇게 되면 그 파티에 있는 진실을 모르는 사람 또한 진실을 아는 사람 그룹에 포함된다.
- 진실을 아는 사람이 전혀 없는 파티에서만 거짓말을 할 수 있다.
이러한 규칙을 가지고 Union & Find를 이용하여 다음과 같은 방법으로 문제를 해결하였다.
- 진실을 아는 사람들을 Union을 이용하여 하나의 집합으로 만든다.
- 각 파티마다 파티에 존재하는 사람들을 Union을 이용하여 하나의 집합으로 만든다.
- 또한 여기서 각 파티마다 한 명씩 뽑아 members라는 리스트에 저장한다.
- 2번 과정에서 만약 진실을 아는 사람이 존재한다면 모르는 사람들 또한 같은 집합에 속하게 될 것이다.
- 이 과정을 모든 파티에 대하여 수행한다.
- 이 과정이 끝나면 사람들은 진실을 아는 사람들과 아닌 사람들도 나뉘게 된다.
- 여기서 members에 있는 사람들을 Find를 이용하여 어떠한 집합에 속해있는지 확인하였을 때, 진실을 아는 사람들의 집합이 아닌 경우라면 count를 1 증가시킨다.
- 최종적으로 count의 값이 거짓말을 할 수 있는 파티의 수이다.
코드는 다음과 같다.
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
|
import sys
def find_parent(parent,x):
if x!=parent[x]:
parent[x] = find_parent(parent,parent[x])
return parent[x]
def union(parent, a,b):
a = find_parent(parent,a)
b = find_parent(parent,b)
if a<b:
parent[b] = a
else:
parent[a] = b
n,m = map(int,sys.stdin.readline().split())
parent = [i for i in range(n+1)]
know_people = list(map(int,sys.stdin.readline().split()))
party = []
for _ in range(m):
party.append(list(map(int,sys.stdin.readline().split())))
if know_people[0] ==0:
print(m)
else:
for i in range(2,len(know_people)):
union(parent,know_people[i-1],know_people[i])
members = []
for j in party:
members.append(j[1])
for k in range(2,j[0]+1):
union(parent,j[k-1],j[k])
count = 0
for i in members:
if find_parent(parent,i) != find_parent(parent,know_people[1]):
count+=1
print(count)
|
cs |
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ/Python] 4485_녹색 옷 입은 애가 젤다지? (0) | 2023.02.13 |
---|---|
[BOJ/Python] 11779_최소비용 구하기 2 (0) | 2023.02.12 |
[BOJ/Python] 1238_파티 (2) | 2023.02.10 |
[BOJ/Python] 16928_뱀과 사다리 게임 (2) | 2023.02.09 |
[BOJ/Python] 10282_해킹 (1) | 2023.02.08 |