public class Solution { private readonly int UNREACHABLE = 1_000_000_007; private readonly int LETTERS = 26; private void FloydWarshall(int n, int[,] distances) { for (int k = 0; k < n; ++k) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { distances[i, j] = Math.Min( distances[i, j], distances[i, k] + distances[k, j] ); } } } } private int[,] ConstructGraph(char[] original, char[] changed, int[] costs) { var distances = new int[LETTERS, LETTERS]; // Everything's unreachable for (var i = LETTERS * LETTERS - 1; i >= 0; --i) { distances[i / LETTERS, i % LETTERS] = UNREACHABLE; } // Go through the possible changes for (var i = 0; i < original.length; ++i) { var (u, v, cost) = (original[i] - 'a', changed[i] - 'a', costs[i]); distances[u, v] = Math.Min(distances[u, v], cost); } // Handle self-loops for (var i = 0; i < LETTERS; ++i) { distances[i, i] = 0; } return distances; } public long MinimumCost(string source, string target, char[] original, char[] changed, int[] cost) { var graph = ConstructGraph(original, changed, cost); FloydWarshall(LETTERS, graph); var minCost = 0; for (int i = 0; i < source.Length; ++i) { var operationCost = graph[source[i] - 'a', target[i] - 'a']; if (operationCost == UNREACHABLE) { return -1; } minCost += operationCost; } return minCost; } }