알고리즘 문제 중 처음으로 하루를 넘긴 문제 !
도대체 몇 번을 푼거야 ㅋㅋ...
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
n_list = [[i] for i in range(n+1)]
for _ in range(m):
command, a, b = map(int, input().split())
if command==0:
n_list[a].extend(n_list[b])
n_list[a] = list(set(n_list[a]))
n_list[b].extend(n_list[a])
n_list[b] = list(set(n_list[b]))
for i in n_list[b]:
n_list[i].extend(n_list[b])
n_list[i] = list(set(n_list[a]))
else:
if b in n_list[a]:
print("YES")
else:
print("NO")
처음에 시도했던 방법은 2차원 리스트를 만들어서 0 커맨드
가 나올 때마다 해당 집합의 원소들의 리스트를 extend 하는 방법이었다.
이 방법의 문제점은,
[[0], [1], [2], [3], [4], [5], [6], [7]]
의 리스트가 있을 때 (0, 1, 3)이라는 명령어가 들어오면
[[0], [1, 3], [2], [1, 3], [4], [5], [6], [7]]
의 형태가 된다.
그런데 만약 (0, 3, 5)라는 명령어가 들어오면
[[0], [1, 3], [2], [1, 3, 5], [4], [3, 5], [6], [7]]
의 형태가 된다.
즉 list[1]에도 5가 포함이 되어야 하는데 그렇지 못한다는 아주 크리티컬한 문제가 생기는 것이다.
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
n_list = [i for i in range(n+1)]
idx = [i for i in range(n+1)]
for _ in range(m):
command = sorted(list(map(int, input().split())))
if command[0]==0:
n_list[command[2]] = n_list[min(idx[command[1]], n_list[command[1]])]
else:
if n_list[command[2]] == n_list[command[1]]:
print("YES")
else:
print("NO")
위에서 조금 달라진 접근이다.
리스트를 만들 때 2개의 리스트를 만들어준다. idx
는 실제 값이고, n_list
는 그 원소가 현재 어디 집합에 속해있는지를 따져주는 list이다.0 커맨드
가 나오면 해당 값의 n_list 값을 동일하게 만들어줄 수 있도록 한다.
여기서 조금만 더 생각했으면 되는데, 아쉽게도 그러질 못했다.
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
n_list = []
for _ in range(m):
command, a, b = (map(int, input().split()))
if command == 0:
for i in range(len(n_list)):
if a not in n_list[i] and b not in n_list[i]:
n_list.append(set(a, b))
else:
for i in range(len(n_list)):
if a in n_list[i]:
if b in n_list[i]:
print("YES")
else:
print("NO")
아예 모든 집합을 다 돌면서 판단하는 방법도 해봤다 ㅎㅂㅎ
물론 시간 초과 뜸 ㅋㅋㅋ
import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000)
n, m = map(int, input().split())
n_list = [i for i in range(n+1)]
def find(x):
if n_list[x] == x:
return x
n_list[x] = find(n_list[x])
return n_list[x]
def union(a, b):
a = find(a)
b = find(b)
if a < b:
n_list[b] = a
else:
n_list[a] = b
for _ in range(m):
command, a, b = map(int, input().split())
if command==0:
union(a, b)
else:
if find(a) == find(b):
print('yes')
else:
print('no')
사실 온전히 내 풀이는 아니다. 도저히 접근 방법을 모르겠어서 인터넷에 어떤 알고리즘을 써야하는지 슬쩍 살펴봤다 ㅋㅎㅋㅎ
사용해야 하는 알고리즘은
union-find
이다. 여기에 대한 설명은 다른 분들이 너무 잘해놓으셨기 때문에, 이 블로그를 보고 오자.
두 번째 풀이에서, 재귀적으로 사용한다는 포인트만 더 가져갔다면 충분히 풀어냈을 법도 했다.
오늘은 다른 풀이가 없다. 사실상 마지막 네번째 풀이가 다른 풀이 ... ㅎㅂㅎ
자료구조라서 만만하게 봤는데 역시 골드4는 다른 것 같다 ㅎ.............
다시 빈 껍데기로 돌아간 나는야 골드........
더더 발전해보자 ~!~!