• 洛谷 P3386 【模板】二分图匹配(匈牙利算法,增广路)


    传送门


    匈牙利算法

    匈牙利算法(别名“找对象游戏”),就是给你一个二分图,求最大匹配。

    最大匹配就是做多能连多少条边。

    我们把这个抽象的概念转化成现实问题——找对象。

    男女两组,男生A组,女生B组,每一个男生都有自己喜欢的女生(可能不止一个),作为上帝的你,尽可能的让更多的人成为男女朋友。

    怎么做呢?

    枚举每一个男生,要求尽可能找到女朋友,但要保证前面的人可以更换女朋友,但是原来有女朋友的现在必须都有女朋友,这样如果能行,那么答案+1。

    枚举所有男生后就得到了答案。

    这就是匈牙利算法的主要思想——增广路

    奉上夏令营zyb老师的课件:

     AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 const int maxn=1000005;
     8 int n,m,E,p[2005],cnt,ans;
     9 bool vis[2005];
    10 int girl[2005];
    11 struct node{
    12     int v,next;
    13 }e[2*maxn];
    14 void insert(int u,int v){
    15     cnt++;
    16     e[cnt].v=v;
    17     e[cnt].next=p[u];
    18     p[u]=cnt;
    19 }
    20 bool work(int u){
    21     for(int i=p[u];i!=-1;i=e[i].next){
    22         if(!vis[e[i].v]){
    23             vis[e[i].v]=1;
    24             if(!girl[e[i].v]||work(girl[e[i].v])){
    25                 girl[e[i].v]=u;
    26                 return true;
    27             }
    28         }
    29     }
    30     return false;
    31 }
    32 int main()
    33 {
    34     memset(p,-1,sizeof(p));
    35     cin>>n>>m>>E;
    36     for(int i=1;i<=E;i++){
    37         int u,v;
    38         scanf("%d%d",&u,&v);
    39         if(u<=n&&v<=m){
    40             insert(u,v+1000);
    41             insert(v+1000,u);
    42         }
    43     }
    44     for(int i=1;i<=n;i++){
    45         memset(vis,0,sizeof(vis));
    46         if(work(i)) ans++;
    47     }
    48     cout<<ans;
    49     return 0;
    50 }
  • 相关阅读:
    题解:luoguP1861 星之器
    题解:LOJ540游戏
    Yii框架常见问题
    常用ubuntu命令
    Python中的映射数据类型 dict
    Python中的编码问题:ASCII码 Unicoden编码 UTF8编码
    Python中的列表、元组的增、删、改、查
    Python 数据类型之 集合 set
    Python中常见的字符串的操作方法:
    Python程序的控制结构用多分支结构处理身体指标BMI问题
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12181706.html
Copyright © 2020-2023  润新知