using
System;
using
System.Collections;
public
class
GFG {
static
int
[, ] cost =
new
int
[31, 31];
static
int
n, max_match;
static
int
[] lx =
new
int
[31];
static
int
[] ly =
new
int
[31];
static
int
[] xy =
new
int
[31];
static
int
[] yx =
new
int
[31];
static
bool
[] S =
new
bool
[31];
static
bool
[] T =
new
bool
[31];
static
int
[] slack =
new
int
[31];
static
int
[] slackx =
new
int
[31];
static
int
[] prev_ious =
new
int
[31];
static
void
init_labels()
{
Array.Fill(lx, 0);
Array.Fill(ly, 0);
for
(
int
x = 0; x < n; x++)
for
(
int
y = 0; y < n; y++)
lx[x] = Math.Max(lx[x], cost[x, y]);
}
static
void
update_labels()
{
int
x, y;
int
delta = 99999999;
for
(y = 0; y < n; y++)
if
(!T[y])
delta = Math.Min(delta, slack[y]);
for
(x = 0; x < n; x++)
if
(S[x])
lx[x] -= delta;
for
(y = 0; y < n; y++)
if
(T[y])
ly[y] += delta;
for
(y = 0; y < n; y++)
if
(!T[y])
slack[y] -= delta;
}
static
void
add_to_tree(
int
x,
int
prev_iousx)
{
S[x] =
true
;
prev_ious[x] = prev_iousx;
for
(
int
y = 0; y < n; y++)
if
(lx[x] + ly[y] - cost[x, y] < slack[y]) {
slack[y] = lx[x] + ly[y] - cost[x, y];
slackx[y] = x;
}
}
static
void
augment()
{
if
(max_match == n)
return
;
int
x = 0, y = 0, root = 0;
int
[] q =
new
int
[31];
int
wr = 0, rd = 0;
Array.Fill(prev_ious, -1);
for
(x = 0; x < n; x++) {
if
(xy[x] == -1) {
q[wr++] = root = x;
prev_ious[x] = -2;
S[x] =
true
;
break
;
}
}
for
(y = 0; y < n; y++) {
slack[y] = lx[root] + ly[y] - cost[root, y];
slackx[y] = root;
}
while
(
true
) {
while
(rd < wr) {
x = q[rd++];
for
(y = 0; y < n;
y++)
if
(cost[x, y] == lx[x] + ly[y]
&& !T[y]) {
if
(yx[y] == -1)
break
;
T[y] =
true
;
q[wr++] = yx[y];
add_to_tree(yx[y], x);
}
if
(y < n)
break
;
}
if
(y < n)
break
;
update_labels();
wr = rd = 0;
for
(y = 0; y < n; y++)
if
(!T[y] && slack[y] == 0) {
if
(yx[y] == -1) {
x = slackx[y];
break
;
}
else
{
T[y] =
true
;
if
(!S[yx[y]]) {
q[wr++] = yx[y];
add_to_tree(yx[y], slackx[y]);
}
}
}
if
(y < n)
break
;
}
if
(y < n) {
max_match++;
for
(
int
cx = x, cy = y, ty; cx != -2;
cx = prev_ious[cx], cy = ty) {
ty = xy[cx];
yx[cy] = cx;
xy[cx] = cy;
}
augment();
}
}
static
int
hungarian()
{
int
ret = 0;
max_match = 0;
Array.Fill(xy, -1);
Array.Fill(yx, -1);
init_labels();
augment();
for
(
int
x = 0; x < n; x++)
ret += cost[x, xy[x]];
return
ret;
}
static
int
assignmentProblem(
int
[] Arr,
int
N)
{
n = N;
for
(
int
i = 0; i < n; i++)
for
(
int
j = 0; j < n; j++)
cost[i, j] = -1 * Arr[i * n + j];
int
ans = -1 * hungarian();
return
ans;
}
static
public
void
Main()
{
int
[] arr = { 3, 5, 10, 1 };
int
N = (
int
)Math.Sqrt(arr.Length);
Console.WriteLine(assignmentProblem(arr, N));
}
}