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