![https://velog.velcdn.com/images/morion002/post/05544472-6c40-4fa6-9431-930adfc76f48/array graph.jpg](https://velog.velcdn.com/images/morion002/post/05544472-6c40-4fa6-9431-930adfc76f48/array graph.jpg)
A
/ \
B---C
| A | B | C |
---|---|---|---|
A | 0 | 1 | 1 |
---|---|---|---|
B | 1 | 0 | 1 |
---|---|---|---|
C | 1 | 1 | 0 |
---|---|---|---|
INF = 999999999
graph = [
[0, 7, 5],
[7, 0, INF],
[5, INF, 0]
]
from QueType import *
from StackType import *
NULL_EDGE = 0
def index_is(vertices, vertex):
index = 0
while index < len(vertices) and vertex != vertices[index]:
index += 1
if not index < len(vertices):
return -1
else:
return index
class GraphType:
def __init__(self, maxV=50):
self.numVertices = 0
self.maxVertices = maxV
self.vertices = [None] * maxV
self.edges = [[NULL_EDGE] * maxV for _ in range(maxV)]
self.marks = [None] * maxV
def add_vertex(self, vertex):
self.vertices[self.numVertices] = vertex
for index in range(self.numVertices):
self.edges[self.numVertices][index] = NULL_EDGE
self.edges[index][self.numVertices] = NULL_EDGE
self.numVertices += 1
def add_edge(self, fromVertex, toVertex, weight):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
self.edges[row][col] = weight
def weight_is(self, fromVertex, toVertex):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
return self.edges[row][col]
def get_to_vertices(self, vertex, adjVertices):
fromIndex = index_is(self.vertices, vertex)
for toIndex in range(self.numVertices):
if(self.edges[fromIndex][toIndex] != NULL_EDGE):
adjVertices.enqueue(self.vertices[toIndex])
def clear_marks(self):
for index in range(self.numVertices):
self.marks[index] = False
def is_marked(self, vertex):
index = index_is(self.vertices, vertex)
return self.marks[index]
def mark_vertex(self, vertex):
index = index_is(self.vertices, vertex)
self.marks[index] = True
def delete_edge(self, fromVertex, toVertex):
row = index_is(self.vertices, fromVertex)
col = index_is(self.vertices, toVertex)
self.edges[row][col] = NULL_EDGE
![https://velog.velcdn.com/images/morion002/post/212ee124-0e10-46cf-85da-2b2a80d06fe6/linked graph.jpg](https://velog.velcdn.com/images/morion002/post/212ee124-0e10-46cf-85da-2b2a80d06fe6/linked graph.jpg)
A
/ \
B---C
A -> [B, C]
B -> [A, C]
C -> [A, B]
graph = [[] for _ in range(3)]
graph[0].append((1, 7))
graph[0].append((2, 5))
graph[1].append((0, 7))
graph[2].append((0, 5))
# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
# 루트 노드가 아니라면 루트 노드를 찾을 때까지 재귀적으로 호
if parent[x] != x:
return find_parent(parent, parent[x])
return 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
위의 방법은 만약 노드가 일렬로 연결되어 있으면 부모의 부모의 부모 노드를 타고 가는 방식으로 비효율적
경로 압축 기법을 통해 모든 노드의 부모 자리에 가장 최상위 부모를 두는 방식 채택 가능
[https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6pADO%2Fbtrb6TQ7hCI%2F3j8KnlaAzGaIXSK1xopTyk%2Fimg.png](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6pADO%2Fbtrb6TQ7hCI%2F3j8KnlaAzGaIXSK1xopTyk%2Fimg.png)
# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
# 루트 노드가 아니라면 루트 노드를 찾을 때까지 재귀적으로 호출
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
# 특정 원소가 속한 집합을 찾기
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())
parent = [0] * (v + 1)
# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
parent[i] = i
# 사이클 발생 유무
cycle = False
for i in range(e):
a, b = map(int, input().split())
# 사이클이 발생한 경우 종료
if find_parent(parent, a) == find_parent(parent, b):
cycle = True
break
# 사이클이 아니라면 합집합 실행
else:
union_parent(parent, a, b)
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())
parent = [0] * (v + 1)
# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
parent[i] = i
# 모든 간선을 담을 리스트와 최종 비용을 담을 변수
edges = []
result = 0
# 간선 정보 입력받기
for i in range(e):
a, b, cost = map(int, input().split())
edges.append((cost, a, b))
# 간선을 비용 순서로 정렬
edges.sort()
# 간선을 하나씩 확인
for edge in edges:
cost, a, b = edge
# 사이클이 발생하지 않을 때만 집합에 포함
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
# 특정 원소가 속한 집합을 찾기
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
# 노드의 개수와 간선의 개수 입력받기
n, m = map(int, input().split())
parent = [0] * (n + 1)
# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, n + 1):
parent[i] = i
for i in range(m):
oper, a, b = map(int, input().split())
# 합집합 연산인 경우
if oper == 0:
union_parent(parent, a, b)
# 찾기 연산인 경우
elif oper == 1:
if find_parent(parent, a) == find_parent(parent, b):
print("Yes")
else:
print("No")
from collections import deque
import copy
# 노드의 개수 입력받기
v = int(input())
# 모든 노드에 대한 진입차수 0으로 초기화
indegree = [0] * (v + 1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화
graph = [[] for i in range(v + 1)]
# 각 강의 시간을 0으로 초기화
time = [0] * (v + 1)
# 방향 그래프의 모든 간선 정보를 입력받기
for i in range(1, v + 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()
# 처음 시작할 때 진입차수가 0인 노드 큐에 삽입
for i in range(1, v + 1):
if indegree[i] == 0:
q.append(i)
while q:
now = q.popleft()
for i in graph[now]:
result[i] = max(result[i], result[now] + time[i])
indegree[i] -= 1
if indegree[i] == 0:
q.append(i)
for i in range(1, v + 1):
print(result[i])
topology_sort()