匈牙利算法。复杂度为O(mn)。
对每个点都找以它为起点的增广路,当找到增广路后,匹配数必定加1。
#include <stdio.h>
#include <string.h>
#define N 505
#define M 10005
struct Vertex
{
int head;
}V[N];
struct Edge
{
int v,next;
}E[M];
int top,match[N];
bool used[N];
void Init()
{
top = 0;
memset(V,-1,sizeof(V));
memset(match,0,sizeof(match));
}
void Add_Edge(int u,int v)
{
E[top].v = v;
E[top].next = V[u].head;
V[u].head = top++;
}
bool dfs(int u)
{
for(int i=V[u].head;i!=-1;i=E[i].next)
{
int v = E[i].v;
if(!used[v])
{
used[v] = true;
if(!match[v] || dfs(match[v]))
{
match[v] = u;
return true;
}
}
}
return false;
}
int main()
{
int z,n,m,u,v;
scanf("%d",&z);
while(z--)
{
Init();
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d",&u,&v);
Add_Edge(u,v);
}
int ans = 0;
for(int i=1;i<=n;i++)
{
memset(used,false,sizeof(used));
if(dfs(i))
++ans;
}
printf("%d\n",ans);
}
return 0;
}