1. Floyd-Warshall All-Pairs Transitive Division
Intuition
Extract all unique variables. Initialize a 2D table ratio[u][v] with -1.0. For each equation, set ratio[A][B] = val, ratio[B][A] = 1/val, and ratio[A][A] = 1.0. Then run Floyd-Warshall with multiplication: if ratio[i][k] > 0 && ratio[k][j] > 0, then ratio[i][j] = ratio[i][k] * ratio[k][j]. All queries are then answered in O(1) time.
Algorithm
- Map each unique variable string to an integer index 0 \dots V - 1.
- Initialize
ratiomatrix of size V × V with -1.0. - For each vertex i, set
ratio[i][i] = 1.0. - For each equation (A, B) with value v:
-
ratio[u][v] = val,ratio[v][u] = 1.0 / val. - Run Floyd-Warshall: triple loop over k, i, j:
- If
ratio[i][k] > 0 && ratio[k][j] > 0: -
ratio[i][j] = ratio[i][k] * ratio[k][j]. - For each query (C, D):
- If C or D not in map, answer is -1.0.
- Else answer is
ratio[idC][idD].
#include <iostream>#include <vector>#include <string>#include <unordered_map> std::vector<double> calcEquationFloyd(std::vector<std::vector<std::string>>& equations, std::vector<double>& values, std::vector<std::vector<std::string>>& queries) { std::unordered_map<std::string, int> idMap; int id = 0; for (const auto& eq : equations) { if (!idMap.count(eq[0])) idMap[eq[0]] = id++; if (!idMap.count(eq[1])) idMap[eq[1]] = id++; } int V = id; std::vector<std::vector<double>> ratio(V, std::vector<double>(V, -1.0)); for (int i = 0; i < V; ++i) ratio[i][i] = 1.0; for (size_t i = 0; i < equations.size(); ++i) { int u = idMap[equations[i][0]], v = idMap[equations[i][1]]; ratio[u][v] = values[i]; ratio[v][u] = 1.0 / values[i]; } for (int k = 0; k < V; ++k) { for (int i = 0; i < V; ++i) { for (int j = 0; j < V; ++j) { if (ratio[i][k] > 0 && ratio[k][j] > 0) { ratio[i][j] = ratio[i][k] * ratio[k][j]; } } } } std::vector<double> results; for (const auto& q : queries) { if (!idMap.count(q[0]) || !idMap.count(q[1])) { results.push_back(-1.0); } else { results.push_back(ratio[idMap[q[0]]][idMap[q[1]]]); } } return results;} int main() { std::vector<std::vector<std::string>> eq = {{"a","b"},{"b","c"}}; std::vector<double> vals = {2.0, 3.0}; std::vector<std::vector<std::string>> q = {{"a","c"},{"b","a"},{"a","e"}}; auto res = calcEquationFloyd(eq, vals, q); std::cout << "Evaluate Division (Floyd): "; for (double d : res) std::cout << d << " "; std::cout << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(V^3 + Q) where V is the number of unique variables (at most 40) and Q is queries count. - Space complexity:
O(V^2) for the all-pairs ratio table.