图匹配板子
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int n, m, e;
int w[N][N];
int vis[N], linkx[N], linky[N];
bool Find(int x) {
for (int i = 1; i <= m; ++i)
if (!vis[i] && w[x][i]) {
vis[i] = 1;
if (!linky[i] || Find(linky[i])) {
linky[i] = x;
return 1;
}
}
return 0;
}
int main() {
scanf("%d%d%d", &n, &m, &e);
for (int i = 1; i <= e; ++i) {
int u, v;
scanf("%d%d", &u, &v);
w[u][v] = 1;
}
int ret = 0;
for (int i = 1; i <= n; ++i) {
memset(vis, 0, sizeof(vis));
if (Find(i)) ++ret;
}
for (int i = 1; i <= m; ++i)
if (linky[i]) linkx[linky[i]] = i;
printf("%d\n", ret);
for (int i = 1; i <= n; ++i)
printf("%d ", linkx[i]);
puts("");
return 0;
}
uoj#80. 二分图最大权匹配
DFS版(复杂度为\(O(n^4)\) Time Limit Exceeded)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 405;
const LL INF = ~0ULL >> 1;
int n, m, e;
int w[N][N];
int vis[N], linkx[N], linky[N];
LL lx[N], ly[N], slack;
bool Find(int x) {
for (int i = 1; i <= max(n, m); ++i)
if (!vis[i]) {
if (lx[x] + ly[i] == w[x][i]) {
vis[i] = 1;
if (!linky[i] || Find(linky[i])) {
linky[i] = x;
return 1;
}
} else slack = min(slack, lx[x] + ly[i] - w[x][i]);
}
return 0;
}
int main() {
scanf("%d%d%d", &n, &m, &e);
for (int i = 1; i <= e; ++i) {
int u, v;
scanf("%d%d", &u, &v);
scanf("%d", &w[u][v]);
lx[u] = max<LL>(lx[u], w[u][v]);
ly[v] = max<LL>(ly[v], w[u][v]);
}
for (int i = 1; i <= max(n, m); ++i)
for (; ; ) {
memset(vis, 0, sizeof(vis));
slack = INF;
if (Find(i)) break;
lx[i] -= slack;
for (int j = 1; j <= max(n, m); ++j)
if (vis[j]) {
lx[linky[j]] -= slack;
ly[j] += slack;
}
}
LL ret = 0;
for (int i = 1; i <= max(n, m); ++i) {
ret += lx[i];
ret += ly[i];
if (w[linky[i]][i]) linkx[linky[i]] = i;
}
printf("%lld\n", ret);
for (int i = 1; i <= n; ++i)
printf("%d ", linkx[i]);
puts("");
return 0;
}
BFS版(复杂度为\(O(n^3)\))
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <class T>
inline bool Cmin(T &a, T b) {
return (a > b) ? (a = b, 1) : 0;
}
const int N = 405;
const LL INF = ~0ULL >> 1;
int n, m, e;
int w[N][N];
int vis[N], linkx[N], linky[N];
LL lx[N], ly[N], slack[N], slap[N];
void BFS(int x) {
memset(vis, 0, sizeof(vis));
fill(slack, slack + max(n, m) + 1, INF);
memset(slap, 0, sizeof(slap));
linky[0] = x;
int y = 0;
while (linky[y]) {
int s = 0;
x = linky[y];
vis[y] = 1;
for (int i = 1; i <= max(n, m); ++i)
if (!vis[i]) {
if (Cmin(slack[i], lx[x] + ly[i] - w[x][i])) slap[i] = y;
if (slack[s] > slack[i]) s = i;
}
LL t = slack[s];
for (int i = 0; i <= max(n, m); ++i)
if (vis[i]) {
lx[linky[i]] -= t;
ly[i] += t;
} else if (slack[i] < INF) slack[i] -= t;
y = s;
}
for (; y; y = slap[y]) linky[y] = linky[slap[y]];
return;
}
int main() {
scanf("%d%d%d", &n, &m, &e);
for (int i = 1; i <= e; ++i) {
int u, v;
scanf("%d%d", &u, &v);
scanf("%d", &w[u][v]);
lx[u] = max<LL>(lx[u], w[u][v]);
ly[v] = max<LL>(ly[v], w[u][v]);
}
for (int i = 1; i <= max(n, m); ++i) BFS(i);
LL ret = 0;
for (int i = 1; i <= max(n, m); ++i) {
ret += lx[i];
ret += ly[i];
if (w[linky[i]][i]) linkx[linky[i]] = i;
}
printf("%lld\n", ret);
for (int i = 1; i <= n; ++i)
printf("%d ", linkx[i]);
puts("");
return 0;
}