• 二分图的判定(染色法)和二分图最大匹配(匈牙利)算法及模板


    定义

      二分图也称二部图,是图论里的一种特殊模型,也是一种特殊的网络流。其最大的特点在于,可以将图里的顶点分为两个集合,且集合内的点没有直接关联,如下图所示。

    如果某个图为二分图,那么它至少有两个顶点,且其所有回路的长度均为偶数,任何无回路的的图均是二分图。

     1.染色法判断二分图

     染色法是对每一个点深搜,与这个点连接的点颜色与此点相反,如果存在环且是偶数环或则不存在环,则满足该条件,如果存在奇数环则不满足(推出矛盾)

    #include<iostream>
    #include<cstring>
    using namespace std;
    int h[100010],e[200010],ne[200010],idx;
    int color[100010];int n,m;
    void add(int a,int b)
    {
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    bool dfs(int u,int c)
    {
        color[u]=c;
        for(int i=h[u];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(!color[j])//未被染色的话
            {
                if(!dfs(j,3-c))return false;
            }
            else if(color[j]==c)//如果领结的点与本点颜色一样,则存在奇数环,不是二分图
            return false;
        }
        return true;
    }
    int main()
    {
        memset(h,-1,sizeof h);cin>>n>>m;
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        int f=1;
        for(int i=1;i<=n;i++)
        {
            if(!color[i])//未被染色的话
            {
                if(!dfs(i,1))
                {
                    f=0;
                    break;
                }
            }
        }
        if(f)printf("Yes
    ");
        else
        printf("No
    ");
        return 0;
    }

    2.匈牙利算法求二分图的最大匹配

    首先介绍两个概念:

    二分图的匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

    二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。

    从左边的二分图一一枚举匹配右边(所以存从左边到右边的有向边就行),对于左边每一个点所连接的右边部分来说,

    如果在这次循环时未被枚举,且未匹配左边的点或则匹配的左边的可以连接其他右边部分的点(递归实现)则该点可以匹配此时右边的点

    #include<iostream>
    #include<cstring>
    using namespace std;
    int n1,n2,m;
    int h[510],e[100010],ne[100010],idx;
    int match[510];//存与n2匹配的n1
    int vis[510];//每一个循环时判断n2是否已经有了匹配;
    void add(int a,int b)
    {
        e[idx]=b;ne[idx]=h[a];h[a]=idx++;
    }
    bool find(int x)
    {
        for(int i=h[x];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(!vis[j])//此时n2未被选择
            {
                vis[j]=1;
                if(match[j]==0||find(match[j]))//如果此时n2未被n1选择,或则与n2选择的n1有其他的选择
                {
                    match[j]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        cin>>n1>>n2>>m;
        memset(h,-1,sizeof h);
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        int res=0;
        for(int i=1;i<=n1;i++)
        {
            memset(vis,0,sizeof(vis));
            if(find(i))res++;
        }
        cout<<res<<endl;
        return 0;
    }
  • 相关阅读:
    微软开源Counterfit,用于AI系统安全测试的自动化工具
    吴恩达教你如何读论文:绘制进度表格,论文至少看三遍,还要问自己问题
    前帝国理工金融数学PhD易聪先生的书单
    以机器学习的视角来看时序点过程的最新进展
    文献阅读第一利器:文献笔记法(Literature Notes)
    死磕论文前,不如先找齐一套好用的工具
    后悔没早点认识论文工具大盘点!
    写论文、搞科研、读大学必备的28款软件。
    2-1-HC32F460(华大)+BC260Y(NB-IOT)基本控制篇(自建物联网平台)-基础外设例程-工程模板使用说明
    1-HC32F460(华大)+BC260Y(NB-IOT)基本控制篇(自建物联网平台)--硬件使用说明
  • 原文地址:https://www.cnblogs.com/flyljz/p/11766389.html
Copyright © 2020-2023  润新知