白駿1707|二分図(DFS&BFS)
問題のソース:https://www.acmicpc.net/problem/1707
質問する
グラフィック頂点のセットを2つに分けると、隣接するすべてのノード間のセットの異なるグラフィックを2つのグラフと呼びます.
グラフィック頂点の個数と幹線情報が与えられると
このグラフはこちらのグラフですか.そうですか.出力の問題.
入力
k:テストケース数(1<=k<=5)
v:頂点数(1<=v<=2000)
e:幹線数(2つの頂点の番号、1<=e<=20000)
問題の処理方法
最初は質問で説明されているこのグラフが何なのか分からなかったので、ウィキペディアを参照.
上の図に示すように、集合情報を色で表現すると分かりやすいようです.
BFSを用いた実施手順
宣言格納集合情報(コードでステータス
status
として表される)のリスト(0:まだグループ化されていません.1:青、2:赤)
開始ノードからBFSを迂回して親ノードと子ノードのstatusを決定する.
1)子ノードの状態がない場合、親ノードの状態とは逆になります.
status[child] = -status[parent]
2)子ノードの状態が親ノードの状態と同じである場合、二分図ではないため、False
が返される.すべてのノードが接続されていない可能性があるので、すべてのノードがまだステータス
status
を持っていない場合、そのノードを先頭ノードとしてBFSが行われる.せきぶん
コレクション情報
status
を表示するには、他のDFS&BFSの問題とは異なり、アクセスされたノードについても、集合情報
status
を表示する必要がある.(アレイへのアクセスは不要)
すべてのノードが接続されていない可能性があります.
各ノードについて、ステータス
status
が0の場合、BFSを実行してノードをグループ化する必要がある.BFSコード
import sys
from collections import deque
def bfs(x):
# 탐색 시작 노드를 큐에 넣고 초기 상태를 1로 설정한다.
queue = deque()
queue.append(x)
status[x] = 1
while queue:
v = queue.popleft()
for i in graph[v]:
# 아직 상태가 없을 경우 부모 노드와 반대로 설정한다.
if status[i] == 0:
status[i] = -status[v]
queue.append(i)
else:
# 이전에 상태를 이미 지정해줬는데
# 부모노드와 자식노드의 상태가 같다면
# 이분 그래프가 아니므로 False를 반환한다.
if status[i] == status[v]:
return False
return True
k = int(sys.stdin.readline())
for _ in range(k):
# v : 정점의 개수, e : 간선의 개수
v, e = map(int, sys.stdin.readline().split())
# graph : 인접 노드 정보, visited : 방문 정보, status : 집합 정보
graph = [[] for _ in range(v + 1)]
status = [0] * (v + 1)
# 간선의 정보 입력 받음
for _ in range(e):
a, b = map(int, sys.stdin.readline().split())
graph[a].append(b)
graph[b].append(a)
"""
(주의) 모든 노드가 연결되어 있지 않고 떨어져 있을 때를 생각해야한다.
(입력 예시)
1 (테스트 케이스 개수)
2 (간선 개수)
1 3 (긴선 정보, 1과 3이 연결되어 있다)
4 5 (긴선 정보, 4와 5가 연결되어 있다)
이렇게 떨어져 있는 그래프 일 수 있으므로 각 노드 별로
인접 노드중에 같은 집합이 있는지를 bfs를 통해 확인한다.
"""
flag = True
for i in range(1, v + 1):
if status[i] == 0:
if not bfs(i):
flag = False
if flag:
print('YES')
else:
print('NO')
いっそ落ちたグラフとは思えない.もっと問題をやりましょう.Reference
この問題について(白駿1707|二分図(DFS&BFS)), 我々は、より多くの情報をここで見つけました https://velog.io/@whddn0221/백준-1707-이분-그래프-DFSBFSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol