자료구조&알고리즘/알고리즘 - 대회 알고리즘
[알고리즘 문제 풀이][완전탐색] 백준 12784번 - 인하니카 공화국
초코쨔응
2022. 2. 13. 16:17
백준 12784번 인하니카 공화국 문제입니다.
(완전탐색 - DFS)
- 문제 설명: https://www.acmicpc.net/problem/12784
- 문제 풀이:
본 문제는 맨 끝 부분 노드 (리프 노드)와 가장 상위에 존재하는 1번 노드 (루트 노드) 사이의 연결을 끊는 문제입니다. 가장 최소로 다이너마이트 개수를 사용하고 싶다고 했으므로, 자식부터 부모로 올라가면서 자신의 아래 자식 사이 길을 끊는 게 이득인지 자신과 부모 사이 길을 끊는게 이득인지 판단하면 됩니다. 이 문제는 어떤 노드가 자식 노드인지 예제에서 주어지지 않아서 BFS를 하기 위해서는 한 번 for 문을 돌면서 찾아야한다는 귀찮음이 있어 대부분 DFS 로 구현한 코드가 많습니다.
- 코드:
(1) DFS 코드
(출처) https://www.acmicpc.net/source/36691655
import sys
input = sys.stdin.readline
def dfs(x):
visited[x] = True
dynamite = 0
for g in graph[x]:
if not visited[g[0]]:
dynamite += min(g[1], dfs(g[0]))
return dynamite if dynamite else 10000
for _ in range(int(input().rstrip())):
N, M = map(int, input().rstrip().split())
if N == 1:
print(0)
else:
graph = [[] for _ in range(N + 1)]
visited = [False for _ in range(N + 1)]
for _ in range(M):
a, b, c = map(int, input().rstrip().split())
graph[a].append((b, c))
graph[b].append((a, c))
print(dfs(1))
(2) BFS 코드
import sys
input = sys.stdin.readline
connect = [[0 for i in range(1000)] for j in range(1000)]
for _ in range(int(input())):
n, m = map(int, input().split())
for i in range(n):
for j in range(n):
connect[i][j] = 0
indegree = [0]*n
# 자식이 준 값
compare = [0]*n
# 반례 처리
if m == 0:
print(0)
continue
for __ in range(m):
a, b, d = map(int, input().split())
indegree[a-1] += 1
indegree[b-1] += 1
connect[a-1][b-1] = d
connect[b-1][a-1] = d
q = []
qs = 0
qe = 0
# 개수가 1인 애들
indegree[0] += 1 # 이것만 부모가 없어서 1이 덜 들어감
for i in range(n):
if indegree[i] == 1:
q.append(i)
qe += 1
compare[i] = 1000000
while qs < qe:
current = q[qs]
qs += 1
indegree[current] -= 1
for i in range(n):
d = connect[current][i]
if d > 0:
connect[i][current] = 0
indegree[i] -= 1
# 내 부모에게 내가 가진 값과 연결 값 중 더 작은 걸 줌
compare[i] += d if d < compare[current] else compare[current]
if indegree[i] == 1:
q.append(i)
qe += 1
break
print(compare[0])
- 실수 포인트 & 반례:
1. 루트 노드만 존재하는 경우
입력
1
1 0
정답
0
2. 그 외 가능한 반례들
입력)
1
7 6
1 2 9
2 3 4
2 4 1
5 1 4
6 5 1
7 5 2
정답)
8
입력)
1
3 2
1 2 2
2 3 1
정답)
1