const int MAXN = 10010;
int VIS[MAXN];
int Y[MAXN];
Vector <int> G[MAXN];
int n;
bool Dfs (int u)
{for
(int i = 0; i < g[u].size (); i++)
{
int v = g[u][i];
if (Vis[v])
continue;
VIS[V] = true;
if (y[v] = = 1 | | DFS (Y[V]))
{
Y[v] = u;
return true;
}
}
return false;
}
int match ()
{
int ans = 0;
memset (y,-1, sizeof (y));
for (int i = 0; i < n; i++)
{
memset (vis, 0, sizeof (VIS));
if (Dfs (i))
ans++;
}
return ans;
}
Hungarian algorithm
const int maxn = 310;
int Lx [maxn], Ly [maxn];
int left [maxn];
bool S [maxn], T [maxn];
int W [maxn] [maxn], n;
bool match (int u)
{
S [u] = true;
for (int i = 1; i <= n; i ++)
{
if (Lx [u] + Ly [i] == W [u] [i] &&! T [i])
{
T [i] = true;
if (! left [i] || match (left [i]))
{
left [i] = u;
return true;
}
}
}
return false;
}
void update ()
{
int a = 1 << 30;
for (int i = 1; i <= n; i ++) if (S [i])
for (int j = 1; j <= n; j ++) if (! T [j])
a = min (a, Lx [i] + Ly [j]-W [i] [j]);
for (int i = 1; i <= n; i ++)
{
if (S [i])
Lx [i]-= a;
if (T [i])
Ly [i] + = a;
}
}
void KM ()
{
for (int i = 1; i <= n; i ++)
{
left [i] = Lx [i] = Ly [i] = 0;
for (int j = 1; j <= n; j ++)
Lx [i] = max (Lx [i], W [i] [j]);
}
for (int i = 1; i <= n; i ++)
{
while (1)
{
memset (S, 0, sizeof (S));
memset (T, 0, sizeof (T));
if (match (i))
break;
else
update ();
}
}
}
}
Hopcroft-karp
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
const int maxn = 3010;
const int INF = 1<<28;
int dx[maxn], dy[maxn];
int cx[maxn], cy[maxn];
vector <int> G[maxn];
int dis;
int n, m;
bool vis[maxn];
bool search()
{
queue <int> Q;
int dis = INF;
memset(dx, -1, sizeof(dx));
memset(dy, -1, sizeof(dy));
for(int i = 0; i < n; i++)
if(cx[i] == -1)
{
Q.push(i);
dx[i] = 0;
}
while(!Q.empty())
{
int u = Q.front(); Q.pop();
if(dx[u] > dis)
break;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(dy[v] == -1)
{
dy[v] = dx[u] + 1;
if(cy[v] == -1)
dis = dy[v];
else
{
dx[cy[v]] = dy[v] + 1;
Q.push(cy[v]);
}
}
}
}
return dis != INF;
}
bool dfs(int u)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(vis[v])
continue;
vis[v] = true;
if(dy[v] == dx[u]+1)
{
if(cy[v] != -1 && dy[v] == dis)
continue;
if(cy[v] == -1 || dfs(cy[v]))
{
cy[v] = u;
cx[u] = v;
return true;
}
}
}
return false;
}
int match()
{
int ans = 0;
memset(cx, -1, sizeof(cx));
memset(cy, -1, sizeof(cy));
while(search())
{
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++)
if(cx[i] == -1 && dfs(i))
ans++;
}
return ans;
}