728x90
해당문제는 문제를 푸느라 굉장히 고생을 했습니다.
- A구역, B구역 으로 나눌 수 있는 경우의 수를 모두 구한다.
- A,B 구역을 나누는 방법은 저는 재귀를 통하여 경우의 수를 만들었습니다.
- 파이썬의 조합 라이브러리를 사용 할 수 있었지만 사용하지 않았습니다.
- A,B 구역을 나눌때 예를들어 N이 6일때 {1,2,3) {4,5,6}와 {4,5,6}, {1,2,3} 이 중복되지 않도록 만듭니다.
- 또한 순열이 아닌 조합으로 만들어야합니다.
- A구역, B구역으로 각각 잘 나누어졌는지 확인한다.
- A, B 구역으로 잘 나누었는지 확인하는 방법은 BFS를 활용 하였습니다.
- 팀에서 특정한 점에서 BFS를 했을때 다른 팀을 거쳐서 가지않고 우리팀을 갈 수 때이어야 합니다.
- A구역, B구역의 인구수의 차이를 구한다.
- 반복문을 돌리면서 인구수 차이를 구합니다.
import sys
from collections import deque
input = sys.stdin.readline
N = int(input())
people = [0] + list(map(int, input().split()))
graph = [[] for _ in range(N+1)]
for i in range(1, N+1):
temp = list(map(int, input().split()))
if temp[0] > 0: # 간선의 개수가 0 이상일 경우
for n in temp[1:]:
graph[i].append(n)
def is_team(team):
queue = deque()
queue.append(team[0])
visit = [False for _ in range(N+1)]
for k in range(N+1):
if k not in team:
visit[k] = True
visit[team[0]] = True
while queue:
new_n = queue.popleft()
for new_n2 in graph[new_n]:
if new_n2 in team and not visit[new_n2]:
visit[new_n2] = True
queue.append(new_n2)
if all(visit):
return True
else:
return False
ans = sum(people)
def people_diff(team, team2):
temp = 0
temp2 = 0
for n in team:
temp += people[n]
for n in team2:
temp2 += people[n]
return abs(temp - temp2)
def make_team(idx, team):
global ans
if team and team[0] > N // 2:
return
if N > len(team) > 0: # 모든 팀이 결성이 되면
team2 = [i for i in range(1, N+1) if i not in team]
if is_team(team) and is_team(team2):
#print(team, team2)
ans = min(people_diff(team, team2), ans)
#print(ans)
for n in range(idx, N + 1):
if n not in team:
team.append(n)
make_team(idx + 1,team)
team.pop()
make_team(1, [])
if ans == sum(people):
print(-1)
else:
print(ans)
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 2096번 : 내려가기 (0) | 2023.10.17 |
---|---|
[백준] 2565번 : 전기줄 (0) | 2023.10.17 |
[백준] 2636번 : 치즈 (0) | 2023.10.17 |
[백준] 1062번 : 가르침 (0) | 2023.10.15 |
[백준] 3055번 : 탈출 (0) | 2023.08.31 |