グラフ(union-find,クルーズ)
38127 ワード
互いに集合する。
2つの
オペレーションプロセス
-1.AとBのルートノードA',B'をそれぞれ検索する.
-2.AをBに設定した親ノード.(親ノードの場合は、より少ない設定を親ノードとします.)
.ルートノードを探すために、親ノードを再帰的に遡ることができます.
def find_parent(parent, x):
if parent[x] != x:
find_parent(parent, parent[x])
return x
def union(parent, a, b):
root_a = find_parent(parent, a)
root_b = find_parent(parent, b)
if root_a < root_b:
parent[b] = root_a
else:
parent[a] = root_b
node, edge_num = map(int, input().split())
parent = [0] * (node + 1)
for i in range(len(parent)):
parent[i] = i
for i in range(edge_num):
A, B = map(int, input().split())
union(parent, A, B)
find関数:現在のノードのルートノードを位置決めします.親リスト:親ノードの真上にあります.
経路圧縮技術。
find関数で再帰を利用すると複雑さに多くの時間がかかります.
これを補うために、親ノードを表す親リストを更新します.
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return x
判別サイクル。
各幹線
-1.ルートノードが異なる場合はunion演算を実行する
-2.互いに同じであれば周期が発生する.
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return x
def union(parent, a, b):
root_a = find_parent(parent, a)
root_b = find_parent(parent, b)
if root_a < root_b:
parent[b] = root_a
else:
parent[a] = root_b
node, edge_num = map(int, input().split())
parent = [0] * (node + 1)
for i in range(len(parent)):
parent[i] = i
# 다른 부분은 동일 하지만
# 아래 부분만 다르다.
# 부모 노드가 같은 경우엔 브레이크 하고 바로 나간다.
-------------------------------------------------------------------------------------------------
cycle = False
for i in range(edge_num):
A, B = map(int, input().split())
if find_parent(parent, A) == find_parent(parent, B):
cycle = True
break
else:
union(parent, A, B)
-------------------------------------------------------------------------------------------------
ストレッチツリー
身長木とは何ですか.
1つのグラフィックには、すべてのノードが含まれ、ループが存在しない部分があります.
クルースカ
最低コストで伸びた木を探します.
最も重要なのは、すべての幹線をソートすることです.
オペレーションプロセス
−1.最小伸長木に含まれるサイクルX
-2.サイクルOは、最小身長ツリーには含まれません.
ex)7ノードに接続するには6本の幹線が必要です.
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return x
def union(parent, a, b):
root_a = find_parent(parent, a)
root_b = find_parent(parent, b)
if root_a < root_b:
parent[b] = root_a
else:
parent[a] = root_b
node, edge_num = map(int, input().split())
parent = [0] * (node + 1)
for i in range(len(parent)):
parent[i] = i
edges = []
results = 0
for i in range(edge_num):
A, B, cost = map(int, input().split())
edges.append((cost, A, B))
# 정렬을 수행.
# 루트 노드들이 다른 것의 경우 사이클이 발생하지 않는다.
# 그러한 노드들 만을 모아 결과를 출력
-------------------------------------------------------------------------------------------------
edges.sort()
for item in edges:
cost, a, b = item
if find_parent(parent, a) != find_parent(parent, b):
results += cost
union(parent, a, b)
print(results)
-------------------------------------------------------------------------------------------------
位相位置合わせ
一連のタスクを順番に実行するアルゴリズム.(方向性に反するものではないことを示す)
方向性があるため、ノードには入力回数があります.
進入車数は?
特定のノードに入る幹線の個数を意味します.
入る回数を表示するリストが必要です
ガイドと呼びましょう.
オペレーションプロセス
-1.キューから要素を取り出し、そのノードから出発する幹線をグラフィックから削除します.
-2.新規アクセス数0のノードをキューに入れます.
入場回数が0未満ではキューに入れません.ループがある場合は0になりません.
from _collections import deque
node, edge_num = map(int, input().split())
#진입차수의 초기화가 필요하다
indegree = [0] * (node + 1)
graph = [[] for i in range(node + 1)]
for _ in range(node):
a, b = map(int, input().split())
graph[a].append(b)
indegree[b] += 1
def topology_sort():
#정렬된 값들을 담을 리스트
result = []
q = deque()
#진입차수가 0인 것을 큐에 담기.
for idx, item in enumerate(indegree):
if not item:
q.append(idx)
while q:
now = q.popleft()
result.append()
for data in graph[now]:
indegree[data] -= 1
if not indegree[data]:
q.append(data)
for i in result:
print(i, end=" ")
topology_sort()
Reference
この問題について(グラフ(union-find,クルーズ)), 我々は、より多くの情報をここで見つけました https://velog.io/@jsin2475/그래프union-find-크루스칼テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol