P3386 【模板】二分图最大匹配

发布时间 2023-12-20 20:21:55作者: 纯粹的

原题链接

洛谷题解很详细,自己写了些理解在代码注释里

代码

#include<bits/stdc++.h>
using namespace std;
int atch[50005]={0};
int vis[50005]={0};
vector<int> G[505];
int weiy(int now)//让now在他的“仓库”里按顺序找下一个能连的右点,找得到返回1,找不到返回0
{
    vis[now]=1;
    for(int i=0;i<G[now].size();i++)//为什么要全部遍历呢?因为有可能一开始霸占我仓库的人明明自己还有多余的仓库却还要来霸占我的仓库,可以让他滚蛋
    {
        int next=G[now][i];
        if(vis[atch[next]])continue;
        if(!atch[next])//接下来分为三种情况,第一种,这个右点没人连,那我就直接连了
        {
            atch[next]=now;
            return 1;
        }
        else if(!vis[atch[next]]&&weiy(atch[next]))//第二种,这个点有人连,但是这个右点连接的左点可以滚蛋,即所连接的左点能不能找到下一个能连的右点。
        {
            atch[next]=now;
            return 1;
        }
        //这个右点现在连的左点动不得,我只能放弃。
    }
    return 0;//不return1就return0
}
int main()
{
    int n,m,e;
    cin>>n>>m>>e;
    for(int i=1;i<=e;i++)
    {
        int x,y;
        cin>>x>>y;
        G[x].push_back(y);
    }

    int ans=0;
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof vis);//确保每一次每个人最多滚蛋一次,一次足矣
        ans+=weiy(i);//一个一个来
    }
    cout<<ans;
    return 0;
}