- 0번~N번까지 총 N+1명의 학생이 있다.
- 처음에는 모든 학생이 서로 다른 팀으로 구분되어 총 N+1 팀이 존재.
- 이 때 팀을 합치는 연산과, 같은팀인지 확인하는 연산을 한다.
- 첫째 줄에 N,M 이 입력됨. M은 총 연산 횟수.
- 다음 M개 줄에는 각각의 연산이 주어짐.(a, b는 N이하의 양의 정수)
-0 a b
: 학생 a가 속한 팀과 학생 b가 속한 팀을 합치는 연산
-1 a b
: 학생 a가 학생 b와 같은 팀에 속하는지 확인하는 연산출력조건) 같은 팀 여부를 확인하는 연산에 대항 한 줄에 하나씩 YES혹은 NO로 출력
n, m = map(int, input().split())
parent = [0]*(n+1)
for i in range(1,n+1):
parent[i] = i
def find_root(parent, x):
if parent[x] != x:
parent[x] = find_root(parent, parent[x])
return parent[x]
def union(a, b, parent):
a = find_root(parent, a)
b = find_root(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
result = []
for i in range(m):
cal_type, x, y = map(int, input().split())
if cal_type == 0:
union(x,y,parent)
else:
if find_root(parent, x) != find_root(parent, y):
result.append('NO')
else:
result.append('YES')
for i in result:
print(i)
def find_parent(parent,x):
# 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
if parent[x] != x:
parent[x] = find_parent(x)
return parent[x]
def union_parent(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, input().split())
parent = [0]*(n+1)
# 부모테이블에서 부모를 자기 자신으로 초기화
for i in range(0, n+1):
parent[i] = i
for i in range(0, m):
oper, a, b = map(int, input().split())
#합집합(union) 연산인경우
if oper == 0:
union_parent(parent, a, b)
#찾기(find) 연산인경우
elif oper == 1:
if find_parent(parent, a) == find_parent(parent, b):
print('YES')
else:
print('NO')
- 첫째줄에 집 개수(N), 길의 개수(M) 입력됨. (N은 2 이상 100,000 이하인 정수), (M은 1이상 1,000,000 이하인 정수)
- 그 다음줄부터 M줄에 걸쳐 길의 정보 입력됨.
- (A,B,C) : A번 집과 B번 집을 연결하는 길의 유지비가 C (1<=C<=1,000)- 전체 집을 2개의 도시로 분할한다. 각 도시 안에서는 임의의 두 집 사이에 경로가 항상 존재하도록 한다. 분리된 두 도시 사이에는 길이 없어도 됨.
- 도시 분할 기준 : 최소 유지비
n, m = map(int, input().split())
parent = [0]*(n+1)
graph = []
for i in range(1,n+1):
parent[i] = i
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
def union_parent(a,b,parent):
a = find_parent(parent, a)
b = find_parent(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
for i in range(m):
a, b, cost = map(int, input().split())
graph.append((cost, a, b))
graph.sort() # cost 기준으로 오름차순 정렬
print(graph)
# 실수 : 모든 간선으로 union 확인 먼저 했음
# 최단 비용 간선부터 차례대로, 사이클 만들지 않으면서 간선 선택
result = []
for j in graph:
cost , a, b = j
if find_parent(parent, a) != find_parent(parent, b):
union_parent(a,b, parent)
result.append(cost)
# 최소 비용으로 전체 노드 연결하는 경로 구하고 최대 비용인 간선에서 자르기
print(sum(result)-max(result))
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
def union_parent(parent, a, b):
a = find_parent(parent, a)
b = find_parent(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
v, e = map(int, input().split()) #v:노드개수, e:간선개수
parent = [0]*(v+1) # 부모테이블 초기화
edges = []
result = 0
#부모테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v+1):
parent[i] = i
for _ in range(e):
a, b, cost = map(int, input().split())
edges.apend((cost, a, b))
# 간선을 비용순으로 정렬
cost.sort()
last = 0 # 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선
for edge in edge:
cost, a, b = edge
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
last = cost # cost로 정렬되어있기 때문에 마지막 cost 값이 가장 클 것
result += cost
print(result - last)
- 첫째 줄에는 강의 수 N을 입력 (1<=N<=500)
- 다음 N개 줄에는 각 강의의 강의 시간과 그 강의를 듣기 위해 먼저 들어야 하는 선수과목 강의들의 번호가 자연수로 주어짐. (강의 시간은 100,000 이하의 자연수)
- 동시에 여러 강의 듣을 수 있음.
- 예를들어 1번(30시간), 2번(20시간), 3번(40시간)이고 3번의 선수과목이 1번과 2번일 때, 3번 강의를 수강하기까지의 최소 시간은 70시간이다.- 각 강의 번호는 1부터 N까지 구성됨. 각 줄은 -1로 끝남.
출력 조건 ) N개의 강의에 대하여 수강하기 까지 걸리는 최소 시간을 한 줄에 하나씩 출력
n = int(input())
time = [0]*(n+1)
pre = [[] for i in range(n+1)]
indegree = [0]*(n+1) #모든 노드에 대한 진입차수는 0으로 초기화
for i in range(1,n+1):
info = list(map(int, input().split()))
time[i] = info[0]
for p in info[1:-1]:
pre[p].append(i)
indegree[i] += 1
from collections import deque
import copy
result = []
time_result = copy.deepcopy(time) #각 노드에 도달하는 모든 경우에 수 중 최장 시간을 모은 리스트
q = deque()
for i in range(1,n+1):
if indegree[i] == 0:
q.append(i)
while q:
now = q.popleft()
result.append(now)
for j in pre[now]:
indegree[j] -= 1
time_result[j] = max(time_result[j], time_result[now] + time[j])
if indegree[j] == 0:
q.append(j)
for i in range(1, n+1):
print(time_result[i])
from collections import deque
import copy
n = int(input())
# 모든 노드에 대한 진입차수를 0으로 초기화
indegree = [0]*(n+1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트(그래프) 초기화
graph = [[] for i in range(n+1)]
# 각 강의 시간을 0으로 초기화
time = [0]*(n+1)
# 방향 그래프의 모든 간선 정보 입력받기
for i in range(1, n+1):
data = list(map(int, input().split()))
time[i] = data[0]
for x in data[1:-1]:
indegree[i] += 1
graph[x].append(i)
# 위상 정렬 함수
def topology_sort():
result = copy.deepcopy(time) #알고리즘 수행결과를 담을 리스트
q = deque() # 큐 기능을 위한 deque 라이브러리 사용
# 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입
for i in range(1, n+1):
if indegree[i] == 0:
q.append(i)
# 큐가 빌 때까지 반복
while q:
# 큐에서 원소 꺼내기
now = q.popleft()
# 해당 원소와 연결된 노드들의 진입차수에서 1뺴기
for i in graph[now]:
result[i] = max(result[i], result[now]+time[i])
indegree[i] -= 1
# 새롭게 진입차수가 0이 되는 노드를 큐에 삽입
if indegree[i] == 0:
q.append(i)
# 위상정렬을 수행한 결과 출력
for i in range(1,n+1):
print(result[i])
topology_sort()