1. 程式人生 > >二分圖最大匹配模板【匈牙利;Dinic最大流】

二分圖最大匹配模板【匈牙利;Dinic最大流】

圖論 n+1 int ret ini article ems 博客 logs

二分圖最大匹配模板【匈牙利;Dinic最大流】


匈牙利算法

int n,m;
vector<int> map[100010];
int match[100010];//保存匹配的互相點
bool vis[100010];

bool dfs(int u)
{
    for(int j=0;j<map[u].size();j++)
    {
        int v=map[u][j];
        if(!vis[v])
        {
            vis[v]=true;
            if(!match[v]||dfs(match[v]))
            {
                match[v]=u;
                return true;
            }
        }
    }
    return false;
}

int solve()
{
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        memset(vis,false,sizeof(vis));
        if(dfs(i))
        ans++;
    }
    return ans;
}

十分簡潔好理解的版,就是不斷找增廣路


Dinic最大流

最大流的版本重點在於建圖
建圖後可套入任何一個最大流模板
求出的最大流即為最大匹配

不會最大流的小夥伴可以看我的博客
圖論算法-網絡最大流【EK;Dinic】

建邊過程
    int n,m,e;
    //n,m分別為兩個點集點數;e為原圖中的邊
    
    cin>>n>>m>>e;
    for(int i=1;i<=e;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v+n,1);//先建原圖的邊,要註意節點編號以題目為準
        add(v+n,u,0);
    }
    
    int s=0,t=n+m+1;//建立超級源點和超級匯點
    for(int i=1;i<=n;i++)
    {
        add(0,i,1);
        add(i,0,0);//將超級源點對X點集每個點引一條容量為1的邊
    }
    for(int i=n+1;i<=n+m;i++)
    {
        add(i,t,1);將Y點集每個點向超級匯點引一條容量為1的邊
        add(t,i,0);
    }

二分圖最大匹配模板【匈牙利;Dinic最大流】