Algorithm/boj

[파이썬] 4803 트리

takeU 2022. 11. 7. 16:09
반응형
import sys
input = sys.stdin.readline

def find_parent(x):
    if parent[x] != x:
        return find_parent(parent[x])
    return x

def union_parent(a, b):
    a = find_parent(a)
    b = find_parent(b)
    if a != b:
        parent[max(a, b)] = min(a, b)
    edge_count[min(a, b)] = edge_count.get(min(a, b), 0) + 1

i = 1
while True:
    n, m = map(int, input().split())
    if not n + m:
        break
    parent = list(range(n))
    node_count, edge_count = {}, {}
    for _ in range(m):
        x, y = map(int, input().split())
        if x > y:
            x, y = y, x
        union_parent(x - 1, y - 1)
    for j, p in enumerate(parent):
        parent_p = find_parent(p)
        if p != parent_p and p in edge_count:
            edge_count[parent_p] += edge_count[p]
            del edge_count[p]
        parent[j] = p = parent_p
        node_count[p] = node_count.get(p, 0) + 1

    ans = 0
    for node in set(parent):
        if node not in edge_count or node_count[node] > edge_count[node]:
            ans += 1
    if ans == 0:
        print(f'Case {i}: No trees.')
    elif ans == 1:
        print(f'Case {i}: There is one tree.')
    else:
        print(f'Case {i}: A forest of {ans} trees.')
    i += 1

유니온파인드

1. 간선을 받아 union_parent 실행과 동시에 해당 부모를 key로하는 edge_count 1 증가

2. union을 한 결과 리스트인 parent의 각 원소의 개수를 세 node_count에 저장

3. 이 때 갱신되지 않은 parent가 있는 경우를 고려해 갱신이 되는 경우 부모의 edge_count에 더해주고 기존 키는 삭제

4. node가 edge_count에 없거나 (노드 한개로 구성되고 간선이 없는 트리), node_count가 edge_count보다 큰 경우(사이클이 존재하지 않는 트리) ans 1 증가

5. 출력

 

반례가 계속 나와서 여러번 틀린 문제