program threads(input, output); const MAX_THREADS = 64; type ThreadArray = array [1..MAX_THREADS] of integer; var numThreads, numNodes : integer; threadsPerNode : integer; weights : array[1..MAX_THREADS, 1..MAX_THREADS] of integer; assigned : array [1..MAX_THREADS] of boolean; nodeCounts : ThreadArray; bestArr : ThreadArray; temp : ThreadArray; bestArrCost : integer; i, j, top, x, y : integer; notDone : boolean; function calc(var inarr : ThreadArray) : integer; var i, j, cost : integer; at : ThreadArray; begin (* for i:= 1 to numThreads do begin write(inarr[i]:1, ' '); end; *) for i:= 1 to numThreads do begin at[inarr[i]] := (i-1) div threadsPerNode; end; cost := 0; for i:= 1 to numThreads do begin for j:= i+1 to numThreads do begin if (at[i] <> at[j]) then begin cost := cost + weights[i, j]; end; end; end; (* writeln(' costs ', cost:1); *) calc := cost; end; procedure recurse(var arr : ThreadArray; len : integer); var i, cost : integer; begin if (len = numThreads) then begin cost := calc(arr); if (cost < bestArrCost) then begin bestArrCost := cost; bestArr := arr; end; end else begin for i:= 1 to numThreads do begin if (not assigned[i]) then begin assigned[i] := true; arr[len+1] := i; recurse(arr, len + 1); assigned[i] := false; end; end; end; end; { recurse } begin readln(numThreads, numNodes); threadsPerNode := numThreads div numNodes; notDone := true; for i:= 1 to numThreads do begin for j:= 1 to numThreads do begin read(weights[i, j]); end; end; for i:= 1 to numThreads do begin nodeCounts[i] := 0; end; bestArrCost := 16000; recurse(temp, 0); (* for i := 1 to numThreads do begin writeln(bestArr[i]:1); end; *) writeln('Communication cost: ', bestArrCost:1); end.