Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬으로 그래프 안에서 특수한 형태의 부분 그래프 개수 구하기


그래프 이론에는 머리(head)발(feet)이라는 두 종류의 정점으로 구성된 특수한 형태의 그래프가 있습니다. 이 그래프는 머리 정점을 정확히 하나만 가지며, 머리를 각 발에 연결하는 k개의 간선으로 이루어집니다. 따라서 무방향·비가중치 그래프가 주어졌을 때, 이 그래프의 정점 분리(vertex disjoint) 부분 그래프 안에서 이러한 특수한 그래프를 모두 찾아내야 합니다. 두 그래프가 공통으로 가지는 정점이 하나도 없을 때, 두 그래프는 정점 분리되어 있다고 정의합니다.

예를 들어 입력이 아래 그림과 같고,

파이썬으로 그래프 안에서 특수한 형태의 부분 그래프 개수 구하기

노드의 수(n) = 5, 발의 수(t) = 2라면 출력은 5가 됩니다. 즉, 주어진 그래프의 정점 분리 부분 그래프 가운데 이러한 특수한 그래프는 총 5개 존재할 수 있습니다.

해결 접근 방법

이 문제는 다음 단계에 따라 해결할 수 있습니다.

  • G := n+1개의 빈 리스트를 담는 새로운 리스트(인접 리스트)를 생성합니다.
  • edges의 각 항목에 대해 다음을 수행합니다.
    • s := item[0]
    • d := item[1]
    • G[s]의 끝에 d를 삽입합니다.
    • G[d]의 끝에 s를 삽입합니다.
  • visit := 새로운 맵(딕셔너리)을 생성합니다.
  • i를 0부터 n까지 반복하며 다음을 수행합니다.
    • v := G[i]
    • v의 크기가 1이면(차수가 1인 정점, 즉 '발'):
      • s := v[0]
      • s가 visit에 없으면 visit[s] := [i]
      • 그렇지 않으면 visit[s]의 끝에 i를 추가합니다.
    • v의 크기가 0이면(고립된 정점): n := n - 1
  • tmp := 0
  • visit의 각 키 k에 대해 다음을 수행합니다.
    • x := visit[k]의 크기 - t
    • x > 0이면 tmp := tmp + x
  • n - tmp를 반환합니다.

알고리즘 동작 원리

이 알고리즘의 핵심은 각 정점의 차수(degree)를 활용하는 것입니다.

  • 차수가 1인 정점은 다른 정점 하나에만 연결되어 있으므로 '발'의 역할을 합니다. 이러한 발들을 연결된 이웃 정점(잠재적인 '머리')을 키로 하여 visit 맵에 그룹화합니다.
  • 차수가 0인 정점은 어느 그래프에도 속하지 못하는 고립 노드이므로 전체 노드 수에서 제외합니다.
  • 하나의 머리에 연결된 발의 수가 t를 초과하면, 초과된 발(x = 발의 수 - t)은 하나의 특수 그래프를 완성하는 데 사용할 수 없으므로 최종 개수에서 차감합니다.

예제

다음 파이썬 구현을 통해 더 잘 이해해 보겠습니다.

def solve(n, t, edges):
    G = [[] for _ in range(n + 1)]
    for item in edges:
        s, d = map(int, item)
        G[s].append(d)
        G[d].append(s)
    visit = {}
    for i in range(n):
        v = G[i]
        if len(v) == 1:
            s = v[0]
            if s not in visit:
                visit[s] = [i]
            else: visit[s].append(i)
        elif len(v) == 0:
            n -= 1
    tmp = 0
    for k in visit:
        x = len(visit[k])-t
        if x > 0:
            tmp += x
    return n - tmp

print(solve(6, 2, [(1,4), (2,4), (3,4), (3,4), (5,3), (6,3)]))

입력

6, 2, [(1,4), (2,4), (3,4), (3,4), (5,3), (6,3)]

출력

5

이 예제에서 노드 1과 2는 머리 4에 연결된 발이고, 노드 5는 머리 3에 연결된 발입니다. t = 2이므로 머리 4는 발 2개와 함께 하나의 특수 그래프를 온전히 이룹니다. 고립된 노드는 전체 개수에서 제외되고, 발이 부족한 그룹은 추가로 차감되지 않으므로 최종 결과는 5가 출력됩니다.