diff --git a/algorithms/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp
index d843f7017e46992d27eee8101248165e0ac5219f..7616b547b1b634a5ee67b3ef64ecdca89cd585eb 100644
--- a/algorithms/graph/articulations_bridges.cpp
+++ b/algorithms/graph/articulations_bridges.cpp
@@ -13,7 +13,8 @@ struct ArticulationsBridges {
   vector<int> arti;
 
   ArticulationsBridges(int N) :
-    N(N), vis(N), par(N), L(N), low(N) {}
+    N(N), vis(N), par(N), L(N), low(N) 
+  { init(); }
 
   void init() {
     fill(all(L), 0);
diff --git a/algorithms/graph/bipartite_match.cpp b/algorithms/graph/bipartite_match.cpp
index e643c3cd2a9d8683ce7cf07b29c8fd80ab15e49c..53bf6120ae244888305a02412d6862e0ba631e1a 100644
--- a/algorithms/graph/bipartite_match.cpp
+++ b/algorithms/graph/bipartite_match.cpp
@@ -10,7 +10,8 @@ struct BipartiteMatching {
   vector<int> vis, match;
 
   BipartiteMatching(int N) :
-    N(N), vis(N), match(N) {}
+    N(N), vis(N), match(N) 
+  { init(); }
 
   void init() {
     fill(all(vis), 0);
diff --git a/algorithms/graph/floyd_warshall.cpp b/algorithms/graph/floyd_warshall.cpp
index 64e0c47773116bd089ae0f85a28bf86d42ba47b7..d52f5bcfb5ef4f798e55065b6b77e2936fec01e4 100644
--- a/algorithms/graph/floyd_warshall.cpp
+++ b/algorithms/graph/floyd_warshall.cpp
@@ -2,17 +2,17 @@
 ///
 /// Time: O(V^3)
 /// Space: O(V^2)
-/// 
-/// Caution:
-///   - If the edge $\{v,u\}$ doesn't exist, then graph[v][u] must be inf.
 
 int dist[MAX][MAX];
 int graph[MAX][MAX];
 
 void floyd_warshall(int n) {
+  mset(dist, inf);
+
   for (int i = 0; i < n; ++i)
     for (int j = 0; j < n; ++j)
-      dist[i][j] = graph[i][j];
+      if (graph[i][j]) 
+        dist[i][j] = graph[i][j];
 
   for (int k = 0; k < n; ++k)
     for (int i = 0; i < n; ++i)
diff --git a/algorithms/graph/travelling_salesman.cpp b/algorithms/graph/travelling_salesman.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2cc22f93d7893afbbe24a669430c1c6547419a7
--- /dev/null
+++ b/algorithms/graph/travelling_salesman.cpp
@@ -0,0 +1,47 @@
+/// Travelling Salesman
+///
+/// Description:
+///   Given a graph and an origin vertex, this algorithm return the shortest
+/// possible route that visits each vertex and returns to the origin. \par
+///   The algorithm works by using dynamic programming, where dp[i][mask]
+/// stores the last visited vertex $i$ and a set of visited vertices 
+/// represented by a bitmask mask. Given a state, the next vertex in the path
+/// is chosen by a recursive call, until the bitmask is full, in which case the
+/// weight of the edge between the last vertex and the origin in returned.
+///
+/// Time: O(2^n * n^2)
+/// Space: O(2^n * n)
+/// 
+/// Status: Tested (Uva10496)
+
+int dp[MAX][1 << MAX];
+int graph[MAX][MAX];
+
+struct TSP {
+  int N;
+
+  TSP(int N) : N(N)
+  { init(); }
+
+  void init() { mset(dp, -1); }
+
+  int solve(int i, int mask) {
+    if (mask == (1 << N) - 1)
+      return graph[i][0];
+
+    if (dp[i][mask] != -1)
+      return dp[i][mask];
+
+    int ans = inf;
+    for (int j = 0; j < N; ++j)
+      if (!(mask & (1 << j)) && (i != j))
+        ans = min(ans, graph[i][j] + 
+            solve(j, mask | (1 << j)));
+
+    return dp[i][mask] = ans;
+  }
+
+  int run(int start) {
+    return run(start, 1 << start);
+  }
+};
diff --git a/caderno.pdf b/caderno.pdf
index b7acedaa4c089045a0c2991694d6e10e389c19bf..1392bc316a66f707dcffa27283608457fcb0c7ab 100644
Binary files a/caderno.pdf and b/caderno.pdf differ