NYOJ239 月老的难题 二分图最大匹配(前向星)

来源:互联网 发布:幼儿学空手道 知乎 编辑:程序博客网 时间:2024/05/17 09:06

题意:

月老准备给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;}


原创粉丝点击