public long Calculate(bool[][] graph) { var size = graph.Length; var bitGraph = new BitSet2048[size]; var init = Enumerable.Range(0, size) .Select(x => true) .ToArray(); for (var index = 0; index < size; index++) { bitGraph[index] = new BitSet2048(graph[index]); } return(Enumerable.Range(0, size) .Select(x => GetDistanceSquareSum(bitGraph, init, x)) .Sum()); }
private static long GetDistanceSquareSum(BitSet2048[] graph, bool[] init, int startIndex) { var size = graph.Length; var queue = new Queue <int>(); var distance = new long?[size]; var notUsed = new BitSet2048(init); var work = BitSet2048.CreateClear(); distance[startIndex] = 0; queue.Enqueue(startIndex); notUsed[startIndex] = false; while (queue.Any()) { var currentIndex = queue.Dequeue(); var currentDistance = distance[currentIndex]; var currentRow = graph[currentIndex]; for (var index = 0; index < work.Clusters.Length; index++) { work.Clusters[index] = notUsed.Clusters[index] & currentRow.Clusters[index]; } var items = work.GetItems(); foreach (var index in items) { distance[index] = currentDistance + 1; notUsed[index] = false; queue.Enqueue(index); } } return(distance .Select(x => x ?? size) .Select(x => x * x) .Sum()); }