김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㄱ
  • GitHubDesktop
  • KMU_WINK
  • 깃허브데스크탑
  • 원격저장소
  • local저장소
  • 로컬저장소
  • Remote저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

•알고리즘(Algorithm )/문제풀이

[백준4803&파이썬] BFS를 활용하여 사이클을 찾아 트리여부를 확인하자

2023. 4. 16. 23:29

# 문제

백준 4803 트리 파이썬 풀이

 

4803번: 트리

입력으로 주어진 그래프에 트리가 없다면 "No trees."를, 한 개라면 "There is one tree."를, T개(T > 1)라면 "A forest of T trees."를 테스트 케이스 번호와 함께 출력한다.

www.acmicpc.net

 

# 코드

import sys
from collections import deque
from collections import defaultdict



def solve(n,m) :
  ddict = defaultdict(list)
  for _ in range(m) :
    a,b = map(int,sys.stdin.readline().split())
    ddict[a].append(b)
    ddict[b].append(a)

  # 1. 트리의 개수를 셀 수 있어야 한다.
  # 2. 트리가 아닌지( 사이클을 가지는지 확인해야 한다)
  # 2-1. 사이클을 구별하기 위해서, 트리를 양방향으로 만들어서 BFS를 돌리고, visit조건으로 판단한다.
  # 2-2. 양방향으로 만들면 visit에서 방금전에 넘어온건 무조건 체킹 되기 때문에, 이전 부모노드를 넘겨주고 해당건은 패스 시키도록 한다.

  T = 0 # 트리의 개수
  visit = [False] * (n+1)

  for i in range(1,n+1) : # 1부터 n까지의 노드(vertex)를 대상으로 삼는다.
    if visit[i] == False : # 방문했던 곳이 아니라면
      isCycle = False
      dq = deque()
      dq.append((i,-1)) # 시작 노드 넣어주기
      visit[i] = True # 시작 노드 방문처리 해주기

      if len(ddict[i]) == 0 : # 혼자 있는 노드
        # print(f"len : {len(ddict[i])}")
        T+=1
        continue

      while len(dq) != 0 :
        cur = dq.popleft() # bfs 활용
        # print(f"{i} : {cur}")

        for next in ddict[cur[0]] : # 다음 방문예정지
          if next == cur[1] :
            continue # 여기가 특수조건, 트리를 양방향으로 표현했기 때문에, visit를 처리하기 위해서

          if visit[next] == True : # 사이클이 생겨버린 것임
            isCycle = True

          if not isCycle and visit[next] == False :
            dq.append((next,cur[0]))
            # print(f"{cur} -> {next}")
            visit[next] = True

      if not isCycle :
        T +=1
  return T


case = 1
while True :
  n,m = map(int,sys.stdin.readline().split())
  if n == 0 and m == 0 :
    break
  result = solve(n,m)

  if result == 0 :
    print(f"Case {case}: No trees.")
  elif result == 1 :
    print(f"Case {case}: There is one tree.")
  else :
    print(f"Case {case}: A forest of {result} trees.")


  case+=1

 

# 풀이

  • 트리는 방향성이 있으며, 사이클이 없다
  • 트리인지 확인하기 위해서는, 사이클을 가지는지 구별해야 한다.
  • BFS를 이용해 문제를 해결하기 위해서, 노드(vertex)간의 연결을 단방향이 아닌 양방향으로 연결시켜줘야 한다.
  • BFS를 이용해  탐색을 하다가 이미 방문했던 곳을 만나게 되면 사이클이 존재하는 경우이다. 이런 경우 해당 그래프집합은 트리로 간주하지 않고 카운팅을 하지 않는다. ( 코드에서는 isCycle로 표현했다. )
  • 양방향으로 맵핑 시켰기 때문에, 두 연결 vertex는 서로가 서로를 항상 바로보고 있고, 이게 cycle처럼 보일 수 있다. 이것을 해결하기 위해서 이전에 어디서 넘어온건지 확인하고 넘어온거였다면 그냥 무시(continue)한다.
  • 외딴섬처럼 혼자 존재하는 노드가 있고 이것도 역시 하나의 트리다. 그리고 이걸 판변하기 위해서는, 연결된 노드의 갯수를 확인하는데 만약 연결된 노드가 아무것도 없다면(0개라면) 트리의 갯수를 카운팅 해주는 조건을 만든다.

 

# 참고

 

[알고리즘] 최소 신장 트리(MST, Minimum Spanning Tree)란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

 

 

[자료구조] 그래프(Graph)란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

저작자표시 (새창열림)

'•알고리즘(Algorithm ) > 문제풀이' 카테고리의 다른 글

[백준1707&파이썬] BFS를 활용하여 이분 그래프를 판별하는 방법  (1) 2023.04.18
[백준2251&파이썬] BFS는 가지치기로 경우의 수를 구하기 적합하며 방문처리의 방법을 생각해보자  (0) 2023.04.17
[백준16932&파이썬] BFS/DFS풀이에서 시간초과가 난다면 전처리방법이 있는지 고민해라  (1) 2023.04.16
[백준1325&파이썬] DFS+DP는 사이클이 없을때 사용 가능하다.  (0) 2023.04.15
[백준2644&파이썬] 재귀식을 이용한 DFS 사용할때는 실패케이스에 대한 반환값을 생각하자  (0) 2023.04.15
    '•알고리즘(Algorithm )/문제풀이' 카테고리의 다른 글
    • [백준1707&파이썬] BFS를 활용하여 이분 그래프를 판별하는 방법
    • [백준2251&파이썬] BFS는 가지치기로 경우의 수를 구하기 적합하며 방문처리의 방법을 생각해보자
    • [백준16932&파이썬] BFS/DFS풀이에서 시간초과가 난다면 전처리방법이 있는지 고민해라
    • [백준1325&파이썬] DFS+DP는 사이클이 없을때 사용 가능하다.
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바