개발/algorithm
[백준 2617번] 구슬 찾기 - python
zzi_on2
2022. 4. 29. 11:59
문제 링크
풀이
처음에는 프로그래머스의 순위 문제처럼 defaultdict을 사용하여 i보다 무거운 사람과 가벼운 사람을 각각 저장하고 두 dict의 길이 중 하나 이상의 개수가 중간값 이상이면 answer + 1 해주는 식으로 풀었다.
근데 아무리 구글링 해봐도 이렇게 푼 사람이 없는지 반례를 찾지 못했다.
from collections import defaultdict
n, m = map(int,input().split())
heavy = defaultdict(set)
light = defaultdict(set)
for _ in range(m):
a, b = map(int,input().split())
# b보다 무거운 거
heavy[b].add(a)
# a보다 가벼운 거
light[a].add(b)
# b보다 무거운 애들은 b보다 가벼운 애들보다도 무거운 것
for i in range(1,n+1):
for l in light[i]:
heavy[l].update(heavy[i])
for i in range(1,n+1):
# b보다 가벼운 애들은 b보다 무거운애들보다 가벼운 것
for h in heavy[i]:
light[h].update(light[i])
answer = 0
# 가볍거나 무거운 것의 개수가 중간값보다 많으면 될 수 없음
for i in range(1,n+1):
h = len(heavy[i])
l = len(light[i])
# 반례 찾다가 혹시나 해서 넣어준 자기 자신은 제외하는 코드
if i in heavy[i] :
h -= 1
if i in light[i]:
l -= 1
if h >= (n+1)//2 or l >= (n+1)//2:
answer += 1
print(answer)
결국 bfs 로 풀었다.
from collections import defaultdict, deque
def bfs(start):
visited = [False] * (n+1)
visited[start] = True
q = deque()
q.append(start)
cnt = 0
# 무거운 거 개수 구하기
while q:
x = q.popleft()
for i in heavy[x]:
if not visited[i]:
visited[i] = True
q.append(i)
cnt += 1
if cnt > n // 2 :
return True
visited = [False] * (n+1)
visited[start] = True
q = deque()
q.append(start)
cnt = 0
# 가벼운 거 개수 구하기
while q:
x = q.popleft()
for i in light[x]:
if not visited[i]:
visited[i] = True
q.append(i)
cnt += 1
if cnt > n // 2 :
return True
return False
n, m = map(int,input().split())
heavy = defaultdict(list)
light = defaultdict(list)
for _ in range(m):
a, b = map(int,input().split())
# b보다 무거운 거
heavy[b].append(a)
# a보다 가벼운 거
light[a].append(b)
answer = 0
for i in range(1,n+1):
if bfs(i):
answer += 1
print(answer)