graph LR A((A)) -- 10 --- B((B)) A -- 15 --- C((C)) A -- 12 --- D((D)) B -- 8 --- C((C)) B -- 9 --- D((D)) C -- 11 --- D((D)) style A fill:#4fc,stroke:#333 style B fill:#4fc,stroke:#333 style C fill:#4fc,stroke:#333 style D fill:#4fc,stroke:#333
graph LR i((i)) -- w_ij --- j((j)) i -- w_ik --- k((k)) j -- w_jk --- k style i fill:#f96,stroke:#333 style j fill:#9cf,stroke:#333 style k fill:#9f9,stroke:#333
flowchart TD A["Complete Graph G"] --> B["๐ฒ MST"] B --> C["๐ข Odd-degree nodes O"] C --> D["๐ Min Perfect Matching M on O"] B --> E["๐ Combine MST โช M โ Multigraph"] D --> E E --> O((o)) style A fill:#ffd,stroke:#333
flowchart TD O((o)) --> F["๐ Eulerian Circuit"] F --> G["โ๏ธ Shortcut โ Hamiltonian Cycle"] G --> H["โ TSP Tour (โค 1.5ร OPT)"] style H fill:#cfc,stroke:#333,stroke-width:3px
graph TB subgraph "MST (n=6)" 0((0)) --- 1((1)) 0 --- 2((2)) 1 --- 3((3)) 1 --- 4((4)) 4 --- 5((5)) end style 0 fill:#ff6,stroke:#333 style 1 fill:#ff6,stroke:#333 style 2 fill:#ff6,stroke:#333 style 3 fill:#ff6,stroke:#333 style 4 fill:#ff6,stroke:#333 style 5 fill:#ff6,stroke:#333
graph TB 0((0)) ---|deg=2| 1((1)) 0 ---|deg=2| 2((2)) 1 ---|deg=3| 3((3)) 1 ---|deg=3| 4((4)) 4 ---|deg=3| 5((5)) style 1 fill:#f44,stroke:#333,stroke-width:2px style 2 fill:#f44,stroke:#333,stroke-width:2px style 3 fill:#f44,stroke:#333,stroke-width:2px style 5 fill:#f44,stroke:#333,stroke-width:2px
graph TB subgraph "MST edges (solid)" 0((0)) --- 1((1)) 0 --- 2((2)) 1 --- 3((3)) 1 --- 4((4)) 4 --- 5((5)) end subgraph "Matching edges (dashed)" 2 -.- 3 4 -.- 5 end style 0 fill:#ff6,stroke:#333 style 1 fill:#f44,stroke:#333,stroke-width:2px style 2 fill:#f44,stroke:#333,stroke-width:2px style 3 fill:#f44,stroke:#333,stroke-width:2px style 4 fill:#ff6,stroke:#333 style 5 fill:#f44,stroke:#333,stroke-width:2px
graph TB subgraph "Combined Multigraph" 0((0)) --- 1((1)) 0 --- 2((2)) 1 === 3((3)) 1 --- 4((4)) 2 === 3((3)) 4 === 5((5)) 4 --- 5((5)) end style 0 fill:#ff6,stroke:#333 style 1 fill:#ff6,stroke:#333 style 2 fill:#ff6,stroke:#333 style 3 fill:#ff6,stroke:#333 style 4 fill:#ff6,stroke:#333 style 5 fill:#ff6,stroke:#333
graph LR subgraph "Eulerian Walk" direction LR 0 --> 1 --> 3 --> 2 --> 0 --> 2 end
graph TB 0((โ )) === 1((โก)) 0 === 2((โข)) 0 -.-x|visited twice| 2 1 === 3((โฃ)) 1 === 4((โค)) 2 === 3 4 === 5((โฅ)) 4 -.-x 5 linkStyle 0 stroke:#4c4,stroke-width:2px linkStyle 1 stroke:#4c4,stroke-width:2px linkStyle 2 stroke:#4c4,stroke-width:2px linkStyle 3 stroke:#4c4,stroke-width:2px linkStyle 4 stroke:#4c4,stroke-width:2px linkStyle 5 stroke:#4c4,stroke-width:2px
flowchart LR subgraph "Eulerian: 0โโ โโขโโกโโ โโฃโโคโโฃโโ โ0" A end subgraph "Shortcut: 0โโ โโขโโกโโฃโโคโ0" B end A -- "โ๏ธ remove duplicates" --> B
xychart-beta title "Cost buildup vs OPT" x-axis ["MST", "Matching", "Total Tour", "OPT"] y-axis "Cost" 0 --> 100 bar [40, 20, 60, 45]
xychart-beta title "Best-known approximation ratios for Metric TSP" x-axis ["1976\n Christofides", "2020\n Karlin-Klein-OveisGharan", "2022\n Improved", "Ultimate Limit\n (unless P=NP)"] y-axis "Ratio" 1.0 --> 2.0 line [1.5, 1.5, 1.5, 1.0]
timeline title A Brief History of TSP 1800s : "Traveling Salesman" mentioned in German traveling salesmen manuals 1930 : Karl Menger formalizes the problem 1972 : Karp proves TSP is NP-complete ๐จ 1976 : Christofides publishes 1.5-approximation ๐ 1990s : Concorde solver cracks 1000+ city instances 2004 : 85,900-city instance solved optimally 2020s : First improvement over Christofides (by 0.0002%)
graph LR subgraph "OPT Tour" direction LR a1((โข)) --- a2((โข)) --- a3((โข)) --- a4((โข)) --- a1 end subgraph "Matching 1 (dashed)" b1((โข)) -.- b2((โข)) b3((โข)) -.- b4((โข)) end subgraph "Matching 2 (dotted)" c1((โข)) -.- c2((โข)) c3((โข)) -.- c4((โข)) end style a1 fill:#f9f style a2 fill:#f9f style b1 fill:#f9f style b2 fill:#f9f style b3 fill:#f9f style b4 fill:#f9f