zoukankan      html  css  js  c++  java
  • 二分图最大匹配

    二分图最大匹配顾名思义就是从二分图上做匹配且匹配数最大。(以下简称二分图匹配)

    所谓二分图便是把一群点分成两个部分,同一部分的不能相互连接所组成的图便是二分图。

    二分图匹配如果想要达到结果最大,那么可以采用贪心的策略。

    便是如果这个点如果想要匹配的那个人已经被匹配上了,可以分两种情况讨论。

    第一种就是如果你所匹配的那个人所匹配的对象还有下家,就抢过来,而那个对象便去找他的下家。

    从而不断找下去。如果都能成功就可以了。要注意成功的意思不意味这你要抢的人还有匹配的对象就可以了而是你要抢的人要抢的人还有匹配的对象,有一条不满足那你也不能匹配。

    当然如果本来就没有人匹配到你相匹配的人,那你很幸运,直接连就好了。

    第二种就是没有成功的情况,可以想到,没有成功的情况最有可能是后面的人,所以后面的人如果不能匹配到想匹配的人的话,就只能孤独了。

    接下来讲代码

    先上代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    int map[1005][1005];//
    int visit[1005],flag[1005];//visit是有没有被访问注意是访问,不是匹配,而flag才是访问
    int n2,m;//
    bool dfs(int a)
    {
        for(int i=1;i<=n2;i++)
        {
            if(map[a][i]&&!visit[i])//如果该节点没有被找到过 注意:在下面的循环中会清零。
            {
                visit[i]=1;//对于a来说被找到了
                if(!flag[i]||dfs(flag[i]))//如果该节点没有被匹配到或者它可以把他抢过来 (第一种情况)
                {
                    flag[i]=a;//就抢过来
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        int n1;
        cin>>n1>>n2>>m;//n1是左边二分图的边,n2是右边二分图的边,m是边数
        memset(map,0,sizeof(map));
        for(int i=1; i<=m; i++)
        {
          int x,y;
          cin>>x>>y;
          if(y>m)//可能会出现比边数大的情况。
          continue;
          map[x][y]=1;
        }
        memset(flag,0,sizeof(flag));
        int ans=0;
        for(int i=1;i<=n1;i++)
        {
          memset(visit,0,sizeof(visit));
          if(dfs(i))
          ans++;//如果匹配到一个人就加上
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Mac如何删除MySQL,Mac下MySQL卸载方法
    MAC下安装与配置MySQL
    mac+apache+php+phpmyadmin集成php开发环境配置
    打开都是“Smart Adobe CC Blocker v1.0”已损坏,打不开。 您应该将它移到废纸篓。
    PHP 字符串函数
    php基础教程-数据类型
    php基础教程-变量
    php基础教程-语法
    php基础教程-必备基础知识
    有关驾考科目二的相关技巧教程
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9201084.html
Copyright © 2011-2022 走看看