문제)
Description
교재와 강의자료를 참고하여 해밀턴 회로 문제를 해결하는 Algorithm 5.6의 구현을 완성하시오.
주어진 무방항 무가중치 그래프 G = (V, E) 에서
해밀턴 회로의 개수를 출력하시오.
Algorithm 5.6을 구현할 때, 출발정점은 1로 간주한다는 것을 주의하시오.
vindex[0] = 1;
hamiltonian(0);
Input
첫째 줄에 정점의 개수 n과 간선의 개수 m이 주어진다.
둘째 줄부터 m개의 간선이 주어진다.
Output
첫째 줄에 해밀턴 회로의 개수를 출력한다.
코드)
def promising(i):
if i == ver_num - 1 and not W[vindex[ver_num - 1]][vindex[0]]:
return False
elif i > 0 and not W[vindex[i - 1]][vindex[i]]:
return False
else:
j = 1
while j < i:
if vindex[i] == vindex[j]:
return False
j += 1
return True
def hamiltonian(i):
global cnt
if promising(i):
if i == ver_num - 1:
cnt += 1
else:
for j in range(2, ver_num + 1):
vindex[i + 1] = j
hamiltonian(i + 1)
if __name__ == "__main__":
ver_num, edge_num = tuple(map(int, input().split()))
W = [[0] * (ver_num + 1) for _ in range(ver_num + 1)]
for _ in range(edge_num):
i, j = tuple(map(int, input().split()))
W[i][j] = 1
W[j][i] = 1
vindex = [0] * (ver_num + 1)
vindex[0] = 1
cnt = 0
hamiltonian(0)
print(cnt)
2번째 코드)
# i번째 정점과 i번 정점은 다른 이야기임, 앞은 순서를 의미, 뒤는 정점의 번호를 의미
def promising(i):
# 유망하지 않는 조건은 총 3가지
# 마지막 남은 정점에 도달했는데, 출발 정점으로 돌아갈 수 없는 경우
# i번째 정점은 i - 1번째 정점과 인접하지 않은 경우
# i번째 정점을 이미 방문했었을 때
if i == ver_num and W[vindex[ver_num]][vindex[1]] == 0:
return False
elif i > 1 and W[vindex[i - 1]][vindex[i]] == 0:
return False
else:
if vindex[i] in vindex[:i]:
# 1~i-1번째 방문 정점들을 봤을 때, i번째 방문 정점과 중복되면 False
return False
return True
def hamiltonian(i):
if promising(i):
if i == ver_num:
# 무사히 끝까지 도달했고, promising 함수에 의해 출발 정점으로 돌아갈 수 있다면
global cnt
cnt += 1
else:
for j in range(2, ver_num + 1):
# 2번 정점부터 차례대로 i + 1번째에 방문함
vindex[i + 1] = j
hamiltonian(i + 1)
if __name__ == "__main__":
ver_num, edge_num = tuple(map(int, input().split())) # 정점과 간선의 개수
W = [[0] * (ver_num + 1) for _ in range(ver_num + 1)] # 인접행렬
for _ in range(edge_num):
i, j = tuple(map(int, input().split()))
W[i][j] = 1
W[j][i] = 1
vindex = [0] * (ver_num + 1) # 순서의 집합
vindex[1] = 1 # 첫 번째 시작은 1번 정점부터
cnt = 0
hamiltonian(1) # 첫 번째 시작부터 찾음
print(cnt)