题意:
月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。
现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。
现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。
假设男孩们分别编号为1~n,女孩们也分别编号为1~n。
题解:根据描述可以看出这是个求最大匹配的问题。用匈牙利算法,但是不可用邻接矩阵建图,数据量大会TLE。所以我选择用前向星。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
using namespace std;
int a[505][505];
int vit[10005];
int f[10005];
int ans,n,k,tot;
int head[10005];
struct node
{
int u;
int next;
};
node b[10005];
void add(int u,int v)
{
b[tot].u=v;
b[tot].next=head[u];
head[u]=tot++;
}
int dfs(int x)
{
for(int y=head[x];y;y=b[y].next)
{
int k=b[y].u;
if(!vit[k])
{
vit[k]=1;
if(f[k]==0||dfs(f[k]))
{
f[k]=x;
return 1;
}
}
}
return 0;
}
void Search()
{
for(int i=1;i<=n;i++)
{
memset(vit,0,sizeof(vit));
if(dfs(i))
ans++;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
//memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
memset(head,0,sizeof(head));
tot=1;
for(int i=1;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
//a[x][y]=1;
add(x,y);
}
ans=0;
Search();
printf("%d\n",ans);
}
return 0;
}