A tour (a Hamiltonian cycle) is a path from a vertex to itself that passes through each other vertex exactly once.
์ด๋ค ๊ทธ๋ํ์์, ์ด๋ค ์ ์ ์์ํด ๋ชจ๋ ์ ์ ์ ๋ฑ ํ ๋ฒ์ฉ๋ง ๋ฐฉ๋ฌธํ๊ณ ๊ทธ ์ ์ ์ผ๋ก ๋ค์ ๋์์ค๋ ๊ฒฝ๋ก. TSP๋ฌธ์ ๋ ์ด ํด๋ฐํ ๋์ ์ฌ์ดํด ์ค ๊ฐ์ฅ ๊ธธ์ด๊ฐ ์งง์ ์ฌ์ดํด์ ์ฐพ๋ ๋ฌธ์ ์ด๋ค.
Let be a graph with .
๊ทธ๋ํ G๊ฐ ์๊ณ , ์ ์ ๋ค์ ์งํฉ V๊ฐ ์๋ค.
์์์ ์ ์ ์ธํ ์ ์ ๋ค๋ก ๋ง๋ค ์ ์๋ permutation์ ๋ชจ๋ ๊ตฌํด์, ์๋์ ์์์ ์ ๋ํด์ค sequence๊ฐ tour๊ฐ ๋๋์ง ์ฆ, ๊ทธ ์์๋ก ์ฐ๊ฒฐ๋์ด ์๋์ง๋ฅผ ํ์ธํ๋ค. ์ฐ๊ฒฐ๋์ด ์๋ค๋ฉด ํด๋ฐํ ๋์ ์ฌ์ดํด ํ๋๊ฐ ๋ฐ๊ฒฌ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ํญ์ ์ต์๊ฐ์ ์ ์งํ๋ C๋ผ๋ ๋ณ์์ ๊ฐ๊ณผ ๋น๊ตํด์ ํ์ํ๋ค๋ฉด ๊ฐฑ์ ํด์ค๋ค.
๐(๐)=ฮ(๐!) ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
Nearest Neighbor(NN). ์์์ ์์ ์์ํด ์ฐ๊ฒฐ๋์๋ ์ ์ ๋ค ์ค ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ์งง์ ์ ์ ์ tour์ ์ถ๊ฐํ๊ณ , ์ด๋ํ ๊ทธ ์ ์ ์์๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์งํํ๋ค. last๋ ๋ฐ๋ก ์ด์ ๋จ๊ณ์ ์ ์ ์ ์๋ฏธ.
๐(๐)=O(๐^2)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง์ง๋ง, heuristic algorithm์ด๊ธฐ์ ๋์ถ๋ tour๊ฐ ๊ฐ๋ฅํ ๋ชจ๋ ํด๋ฐํ ๋์ ์ฌ์ดํด ์ค์์ ๊ฐ์ฅ ์งง์ tour์ธ์ง (optimal ํ์ง) ๋ณด์ฅํ ์ ์๋ค. optimal๊ณผ ๊ทผ์ ํ๊ธด ํ๋ค.
์ค์ ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฐ๋ก๊ฐ ์๊ธธ ์ ์๋ค.
์์ ๋ฐฉ๋ฒ์ ํตํด tour๋ฅผ ๊ตฌ์ฑํ๋ฉด a - d - e - b - c - f - a ๊ฐ ๋์ค๊ณ ๊ธธ์ด๋ 12์ด๋ค.
ํ์ง๋ง ๊ฐ์ฅ ์งง์ tour๋ a - b - c - f - e - d - a ์ด๊ณ ๊ธธ์ด๋ 10์ด๋ค.
T๋ฅผ optimal tour๋ผ๊ณ ๊ฐ์ ํ๊ณ , ๊ทธ tour๋ฅผ V_pi์์ ์๋ผ์ V_1๊น์ง ๋๋ฌํ๋ ๊ฒฝ๋ก๋ฅผ P๋ผ๊ณ ํ์. ์ฐ๋ฆฌ๋ ์ ์ฒด ์ต์ ์ ํด T์์ ๋ฝ์๋ธ ๋ถ๋ถ P ๋ํ ์ต์ ์ธ์ง๋ฅผ ์ฆ๋ช ํ๊ณ ์ถ๋ค.
๊ทผ๋ฐ ๋ง์ฝ P์ ๊ฐ์ด V_pi์์ ์์ํ์ง๋ง V_1๊น์ง ๋๋ฌํ๋ ๊ฒฝ๋ก๊ฐ ๋ค๋ฅด๋ฉด์, P ๋ณด๋ค ๋ ์งง์ ๊ฑฐ๋ฆฌ๋ก V_1์ ๋๋ฌํ ์ ์๋ ๊ฒฝ๋ก๋ฅผ P'๋ผ๊ณ ํ์. ๊ทธ๋ ๋ค๋ฉด ์๊น P๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ ์๋ฅธ V_pi์์ ๊ทธ ์ด์ ์ ๊ฒฝ๋ก ์ฆ, T-P ์ P'์ ๋ํ T'(T' = T-P + P')์ T๋ณด๋ค ๋ ์งง์ tour์ผ ๊ฒ์ด๋ค. T-P๋ ๋ณํจ์ด ์์ง๋ง P ๋ณด๋ค ๋ ์งง์ P'์ด ๋ํด์ก๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ์ด๋ ๋งจ ์ฒ์์ T๋ฅผ optimal tour๋ผ๊ณ ๊ฐ์ ํ๋ ๊ฒ์ ๋ชจ์์ด๋ค.
๊ทธ๋์ P๊ฐ V_pi ๋ถํฐ ์์ํด V_1๊น์ง ๋๋ฌํ๋ ๊ฒฝ๋ก์ค ์ต์ ์ ๊ฒฝ๋ก(๋ถ๋ถ ์ต์ ์ ํด)๊ฐ ๋๋ ๊ฒ์ด๊ณ , '์ต์ ์ ๋ถ๋ถ๋ ์ต์ ์ด ๋๋ค'๋ ๊ฒ์ด ์ฆ๋ช
๋ ๊ฒ์ด๋ค.
๊ทธ ์์ค์ P๋ฅผ ๋ค์ ์ ์ฒด๋ก ๋๊ณ ๋ค์ ๋ถ๋ถ์ผ๋ก ๋๋ ์ ๊ฐ์ ์ฆ๋ช ์ ํ ์ ์๋ค. P ๊ฒฝ๋ก์์ ์ฒ์๊ณผ ๋์ ์ ์ธํ ์ด๋ ์ ์ ์ ๊ณจ๋ผ ๋ค์ ๋ถ๋ถ์ ์์ฑํ๊ณ ๊ฐ์ ์ฆ๋ช ์ ํ๋ค. ๊ทธ๋ฌ๋ฉด ๊ทธ ๋ถ๋ถ์ ๋ ์ต์ ์์ด ์ฆ๋ช ๋๋ค.
์ด๋ฐ ์๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ, DP๋ฅผ ๋ฌธ์ ์ ์ ์ฉํ ์ ์๋ค.
D[V_i][A]๊ฐ ๊ฐ๋ ๊ฐ์ ์๋ฏธ๋ V_i๋ก ์์ํด์ A์ ์๋ ์ ์ ๋ค์ ํ ๋ฒ ์ฉ๋ง ๊ฑฐ์ณ V_1(์์์ )์ผ๋ก ๊ฐ ์ ์๋ ๊ฒฝ๋ก ์ค ๊ฐ์ฅ ์งง์ ๊ฒฝ๋ก์ ๊ธธ์ด์ด๋ค.
์ ํ์์ ์๋ฏธ๋ ์๊น principle of optimality์์ ์ค๋ช
ํ ๋ด์ฉ์ ๋ค์ ์ ์ฉํ ์ ์๋ค. ๋ถ๋ถ์ ๋๋๋ (V_i ~ V_1์์) V_j์ผ๋ก ์๋ฅด๋ฉด V_j๋ถํฐ ๋ค๋ ๋ค ์ต์ ์ด๊ณ (์ฌ๋ฌ๊ฐ์ง๋ฅผ ํ์ธํด์ ๊ฐ์ฅ ์ต์ ์ ๊ณ ๋ฅผ ์์ ์ด๊ณ ) ๊ทธ ์ต์ ๊ฐ์ V_i ~ V_j ์ ๊ฐ์ ์ ๋ํด์ฃผ๋ฉด ์ ์ฒด ์ต์ ์ด ๋์ฌ ์ ์๋ค. ์ด ์ค๋ช
์ ๋ค์ผ๋ฉด top-down ๋ฐฉ์์ฒ๋ผ ๋๊ปด์ง์ง๋ง, ์ฌ๊ท๋ก ๊ตฌํํ ๋ ํํ๋ง top-down์ด ๋๊ณ ์ค์ ๋ก dpํ
์ด๋ธ์ bottom-up์ผ๋ก ์ฑ์์ง๋ค.
์์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด DP ๋ฐฉ์ ๋ํ ์์ ํ์์ฒ๋ผ ํธ๋ฆฌ๊ฐ ๊ตฌ์ฑ๋๋ ๊ฒ์ ์ ์ ์๋ค.
๊ฐ ๋
ธ๋๋ ํด๋น ๊ตฌ์ฑ์ ๋ํ ์ต์ ์ '๋ณด์ฅ'ํ๋ค. ์๋ฅผ ๋ค์ด B:{C}
๋ B์์ ์์ํด C๋ฅผ ๊ฑฐ์ณ ์์(A)๋ก ๊ฐ๋ ์ต์ ์(๊ฐ์ฅ์งง์) ๊ฐ์์ด ๋ณด์ฅ๋๋ค.
๊ทผ๋ฐ D:{B,C}
๋ํ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ต์ ์ ๋ณด์ฅํด์ผ ํ ํ
๋ฐ, ํธ๋ฆฌ์์ D:{B,C}
์ ํด๋นํ๋ ๋
ธ๋๊ฐ 2๊ฐ์ด๋ค. ๋ฐ๋ผ์ ๋์ ๊ฐ์ ๋น๊ตํด ์ต์ ๊ฐ์ ์ทจํ๋ค. ์ต์ ๊ฐ์ด ํ์ธ๋ ๊ฒฝ์ฐ์ ์๋ ๊ทธ ๊ฐ์ DPํ
์ด๋ธ์ ์ ์ฅํ๋ค. ๋ค๋ฅธ ๊ฒน์น๋ ๋
ธ๋๋ค๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ต์ ๊ฐ์ ์ทจํ๊ณ ์ ์ฅํ๋ค๋ฉด ์๋์ ๊ฐ์ ๊ทธ๋ฆผ์ด ๋ ์ ์๋ค.
์ด์ฒ๋ผ, ๊ฐ๋ฅํ ๊ฒฝ๋ก์ ๊ฒฝ์ฐ์์๋ฅผ ๋ฐ์ง๋, ์ต์ ์์ ๋ณด์ฅํ๋ ๋ถ๋ถ๋ค์ ์ ์ฅํด์ ๋ค์ ํ์ฉํ๋ DP์ ๋ฐฉ์์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
๊ฒฐ๊ตญ ์์ ๊ฐ์ด ๊ฐ์ฅ ๋ง์ง๋ง A:{B,C,D}
์ ์ ์ฒด ๋ฌธ์ ์ ๋ํ ์ต์ ์ด ์ ์ฅ๋๋ค.
ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋
ธ๋์ ๊ฐ์๊ฐ ์๊ฐ๋ณต์ก๋์ ๊ด๋ จ์ด ์์ ๊ฒ์ธ๋ฐ, ์ด๋ ์์ ๊ทธ๋ฆผ์์ ๋ณด์ด๋ฏ ์์์ ์ (A)๋ฅผ ์ ์ธํ ๋๋จธ์ง ์ ์ ๋ค์ ๋ํ ๋ถ๋ถ์งํฉ๊ณผ ๊ด๋ จ์๋ค.
๋๋จธ์ง ์ ์ ๋ค B,C,D๋ฅผ ๊ฐ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๋ก ๋ค์ ์๊ฐํด๋ณด์. ๊ทธ๋ฌ๋ฉด B์ ๊ฒฝ์ฐ ๋จ์ ์ ์ ์ด C์ D์ด๋ฏ๋ก {C,D}์ ๋ํ ๋ถ๋ถ์งํฉ 2^2
๊ฐ๊ฐ ๋์จ๋ค. ๋๋จธ์ง C, D์ ๋ํ ๋ถ๋ถ๋ฌธ์ ๋ํ ๋ง์ฐฌ๊ฐ์ง ์ด๋ฏ๋ก ์์ฑ ๊ฐ๋ฅํ ๋
ธ๋์ ๊ฐ์๋ 2^2 * 3
. ์ด๊ฒ์ ์ผ๋ฐํ ํด๋ณด์๋ฉด, ๋งจ์ฒ์ ๋ชจ๋ ์ ์ ์ ๊ฐ์๋ n ์ด๋ฏ๋ก (2^(n-2)) * (n-1)
์ด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ ๋
ธ๋์์ ์ต์ ์ด ๊ฒฐ์ ๋๊ธฐ ์ , ๊ทธ ๋
ธ๋์ ๊ฐ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ํ์ธํด์ผํ๋ค. ์๋ฅผ ๋ค์ด C:{B,D}
๋
ธ๋์ ๊ฒฝ์ฐ D:{B}
, B:{D}
๋
ธ๋๋ฅผ ํ์ธ(๋ถ๋ถ๋ฌธ์ ๊ฐ ๋ฐํํ๋ ์ต์ ๋ค์ ๋น๊ตํด ํ์ฌ ๋
ธ๋์ ์ต์ ์ ๊ฒฐ์ )ํด์ผ ํ๋ค. ๋ฐ๋ผ์ ์ด๋ ๋
ธ๋์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ง๋ง ์ต๋ O(n)์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ํ ์ ์๋ค.
๋ฐ๋ผ์ ์ ์ฒด ์๊ฐ ๋ณต์ก๋๋ O(n) x O(n * 2^n) -> O(n^2 * 2^n)
์ด ๋ ์ ์๋ ๊ฒ์ด๋ค. brute-force ๋ฐฉ๋ฒ ์ฌ์ฉ์์ O(n!)
๋ณด๋ค ๋ง์ด ๊ฐ์ ๋ ์๊ฐ์์ ์ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด DPํ
์ด๋ธ์ ํด๋น ๋
ธ๋์ ๊ฐ์ ์ ์ฅํด์ผ ํ๋๋ฐ, ํ
์ด๋ธ ๊ตฌ์ฑ์ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ? ํ์ ๊ฐ ์ ์ ์ ์ด๋ฆ, ์ด์ ๊ฐ ์ ์ ๋ค์ด ๊ฒฝ๋ก์ ํฌํจ๋์๋์ง ์ฌ๋ถ๋ฅผ ๋ด์ ์ ๋ณด๋ก ๊ตฌ์ฑํด์ผ ํ๋ค. ๊ฐ ์ ์ ๋ค์ด ๊ฒฝ๋ก์ ํฌํจ๋์ด ์๋์ง๋ฅผ '๋นํธ๋ง์คํน'์ ํตํด ํํํ๋ค.
A, B, C, D 4๊ฐ์ ์ ์ ์ด ์์ ๋ ๊ฐ ์ ์ ์ด ํฌํจ(1), ๋ฏธํฌํจ(0)๋ ๊ฒฝ์ฐ๋ฅผ ๋ชจ๋ ์ธ๋ฉด 2^4=16 ๊ฐ์ง์ ๊ฒฝ์ฐ์ ์๊ฐ ์๋ค. ๊ทธ๋์ ์ด๋ฅผ 0๋ถํฐ 15๊น์ง์ ์ญ์ง์๋ฅผ ํตํด ๊ฐ๊ฐ์ ๊ฒฝ์ฐ๋ฅผ ํน์ ํ ์ ์๋ค.
์ ์ ์ ๊ฐ์๋งํผ ์ด์ง์์๋ฆฌ๊ฐ ์๊ธด๋ค.
์๋ฅผ ๋ค์ด A์ C๊ฐ ํฌํจ๋ ๊ฒฝ์ฐ๋
DCBA
0101(2) = 5 ๋ผ๋ ๊ฐ์ผ๋ก ํํ๋ ์ ์๋ค.
๋ํ ์ด๋ ๊ฒ ํํ๋ ๊ฐ์์ ํน์ ์ ์ ์ด ํฌํจ๋์ด ์๋์ง๋ฅผ ํ์ธํ ๋๋ ์ด์ง๋ฒ์ ์ ๊ทน ํ์ฉํ๋ค. ์์ ๋ ์์์ C๊ฐ ํฌํจ๋์ด์๋์ง ์ฌ๋ถ๋ฅผ ์ดํด๋ณผ ๋ C๊ฐ i๋ฒ์งธ ์ ์ ์ด๋ผ๊ณ ํ๋ฉด, 5 & (1 << i)
์ฐ์ฐ์ ํตํด ํ์ธํ ์ ์๋ค.
- 'a << b' ์ฌํํธ ์ฐ์ฐ์ a๋ฅผ ์ด์ง์๋ก ํํํ์ ๋ ๊ฐ ์ซ์๋ฅผ ์ผ์ชฝ์ผ๋ก b์นธ ์ด๋ํ ๊ฐ์ ์ค๋ค.
4(100) << 2
๋16(10000)
์ด ๋๋ค.- 'a & b' ์ฐ์ฐ์ a์ b๋ฅผ ๊ฐ๊ฐ ์ด์ง์๋ก ํํํ์ ๋ ์ด๋ค ์๋ฆฌ์์ ์๊ฐ ๋๋ค 1์ด๋ฉด ๊ทธ ์๋ฆฌ์ 1์ ๋ฐํํ๋ค. ์๋ฅผ ๋ค์ด
10 & 5
๋4
๊ฐ ๋๋ค.1110 = 10 0101 = 5 ---- 0100 = 4
์์ ๊ฐ์ ์ฐ์ฐ์ ํ์ฉํ๋ฉด, C๋ 2๋ฒ์งธ(0๋ถํฐ์์) ์ ์ ์ด๋ฏ๋ก
0101 = 5
0100 = 4 = 1 << 2(๋ฒ์งธ)
----
0100 = 4 (0์ด ์๋)
์ด๋ผ๋ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค. ์ ๋ฆฌํด๋ณด๋ฉด ํด๋น ์ฐ์ฐ์ ํตํด ํฌํจ์ฌ๋ถ๋ฅผ ํ์ธํ ๋ 0(0000)์ด ๋์จ๋ค๋ฉด ํฌํจ๋์ง ์์๋ค๋ ๋ป์ด๊ณ , 0์ด ์๋ ์ด๋ค ๊ฐ(0100)์ด ๋์๋ค๋ฉด ํฌํจ๋์๋ค๋ ๋ง์ด ๋๋ค. ์ด๋ฅผ ๊ตฌํ์์ ํ์ฉํ๋ฉด ๋ฐฐ์ด์ ์ฌ์ฉํ ํฌํจ์ฌ๋ถ ๊ฒ์ฌ๋ณด๋ค ํจ์ฌ ์๊ฐ์ ์ค์ผ ์ ์๋ค. ์ฌํํธ ์ฐ์ฐ์ ๋น ๋ฅธ ์ฐ์ฐ์ ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐฑ์ค 2098๋ฒ ์ธํ์์ํ ๋ฌธ์ ๋ฅผ ํตํด DP์ BitMasking์ ํ์ฉํ TSP ๊ตฌํ์ ํด ๋ณผ์ ์๋ค.
import sys
n = int(input())
w = []
for _ in range(n):
w.append(list(map(int, sys.stdin.readline().split())))
dp = [[-1] * (1<<(n-1)) for _ in range(n)] # ์ด์ฐจํผ ์์ ์ ์ ์ ์ด์ง์ ์๋ฆฌ๋ ํญ์ 1์ด๊ธฐ ๋๋ฌธ์ ํ์นธ ์ค์ฌ์.
# n-1๊ฐ์ bit๋ก ๋ง๋ค ์ ์๋ ๊ฒฝ์ฐ์ ์๋ 1<<(n-1).
# ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ์์๋ํ ์ญ์ง์ i๋ 0 <= i <= 1<<(n-1) - 1
# ๊ทธ๋์ ํจ์ ํธ์ถ์ ๋ชจ๋ ํฌํจํ๋ ๊ฒฝ์ฐ์ ๋ํ ์ญ์ง์๋ฅผ 1<<(n-1) - 1 ๋ก ์ค๋ค.
def go(i, included):
if not included and w[i][0]: # v_i : {}
# ๋ชจ๋ ์๋ฆฌ์๊ฐ 0์ธ ์ํฉ.
# ์ฆ ์๋ฌด ์ ์ ๋ ์๊ฑฐ์น๊ณ v_i์์ ์์์ ์ ์ผ๋ก ๊ฐ๋ ๋น์ฉ = ํด๋น ๊ฐ์ ์ ๋น์ฉ์ด ๋๋ค.
dp[i][included] = w[i][0]
if dp[i][included] < 0: # ์ง๊ธ ํธ์ถ๋ ๋ถ๋ถ๋ฌธ์ ์ ๋ํ ์ต์ ์ด ๊ตฌํด์ง์ง ์์๋ค๋ฉด = ํด๋น DPํ
์ด๋ธ ๊ณต๊ฐ์ด ํ ๋ฒ๋ ๊ฑด๋๋ ค์ง์ง ์์๋ค๋ฉด, ๋ค์ ํ์ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ์์ฑํด ์ต์ ์ ๊ตฌํ๋ค.
min_ = 1 << 32
for j in range(1,n):
if included & (1<<(j-1)) and w[i][j]: # ๊ฐ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ด๋ค.
# ์ค๊ดํธ ์์ ํฌํจ๋ ์ ์ ์ ์๋ฆฌ์๋ 1์ด๋ค.
length = w[i][j] + go(j, included - (1<<(j-1)))
if length < min_ : min_ = length
dp[i][included] = min_
return dp[i][included]
go(0, (1<<(n-1))-1)
print(dp[0][(1<<(n-1))-1])
ํจ์๊ฐ ์ฌ๊ทํธ์ถ์ ํตํด top-down๋ฐฉ์์ผ๋ก ๋ถ๋ถ๋ฌธ์ ๋ก ํ๊ณ ๋ค์ง๋ง, ๊ฒฐ๊ตญ DP ํ
์ด๋ธ์ v_i : {}
์ธ ๊ฒฝ์ฐ๋ถํฐ, ์ฆ bottom-up์ ๋ฐฉํฅ์ผ๋ก ์ฑ์์ง์ ๋ช
์ฌํด์ผ ํ๋ค.
ใ ใท ใท