-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathhungarian.cpp
More file actions
98 lines (94 loc) · 2.08 KB
/
hungarian.cpp
File metadata and controls
98 lines (94 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template <class T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define int long long int
#define pb push_back
#define pi pair<int, int>
#define pii pair<int, pi>
#define fir first
#define sec second
#define MAXN 505
#define mod 998244353
struct hungarian
{
int n, inf;
vector<vector<int>> a;
vector<int> u, v, p, way;
hungarian(int n_) : n(n_), u(n + 1), v(n + 1), p(n + 1), way(n + 1)
{
a = vector<vector<int>>(n, vector<int>(n));
inf = numeric_limits<int>::max();
}
void add_edge(int x, int y, int c)
{
a[x][y] = c;
}
pair<int, vector<int>> run()
{
for (int i = 1; i <= n; i++)
{
p[0] = i;
int j0 = 0;
vector<int> minv(n + 1, inf);
vector<int> used(n + 1, 0);
do
{
used[j0] = true;
int i0 = p[j0], j1 = -1;
int delta = inf;
for (int j = 1; j <= n; j++)
{
if (!used[j])
{
int cur = a[i0 - 1][j - 1] - u[i0] - v[j];
if (cur < minv[j])
minv[j] = cur, way[j] = j0;
if (minv[j] < delta)
delta = minv[j], j1 = j;
}
}
for (int j = 0; j <= n; j++)
{
if (used[j])
u[p[j]] += delta, v[j] -= delta;
else
minv[j] -= delta;
}
j0 = j1;
} while (p[j0] != 0);
do
{
int j1 = way[j0];
p[j0] = p[j1];
j0 = j1;
} while (j0);
}
vector<int> ans(n);
for (int j = 1; j <= n; j++)
ans[p[j] - 1] = j - 1;
return make_pair(-v[0], ans);
}
};
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<vector<int>> c(n, vector<int>(n));
hungarian h(n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> c[i][j];
h.add_edge(i, j, c[i][j]);
}
}
cout << h.run().fir << endl;
return 0;
}