• [UOJ] #78. 二分图最大匹配


    #78. 二分图最大匹配

    从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生。编号分别为 1,,nl1,…,nl 和 1,,nr1,…,nr。

    有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为配偶。

    请问这个班级里最多产生多少对配偶?

    输入格式

    第一行三个正整数,nl,nr,mnl,nr,m。

    接下来 mm 行,每行两个整数 v,uv,u 表示第 vv 个男生和第 uu 个女生愿意结为配偶。保证 1vnl1≤v≤nl,1unr1≤u≤nr,保证同一个条件不会出现两次。

    输出格式

    第一行一个整数,表示最多产生多少对配偶。

    接下来一行 nlnl 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生的配偶的编号。如果 vv 号男生没配偶请输出 00。

    样例一

    input

    2 2 3
    1 1
    1 2
    2 1
    
    

    output

    2
    2 1
    
    

    explanation

    11 号男生跟 22 号女生幸福地生活在了一起~

    22 号男生跟 11 号女生幸福地生活在了一起~

    样例二

    input

    2 2 2
    1 1
    2 1
    
    

    output

    1
    1 0
    
    

    explanation

    班上一个女神一个女汉子,两个男生都去追女神。一种最优方案是:

    11 号男生跟 11 号女生幸福地生活在了一起~

    22 号男生孤独终生。= =||

    限制与约定

    1nl,nr5001≤nl,nr≤500,1m2500001≤m≤250000。

    时间限制1s

    空间限制256MB

    下载

    样例数据下载

    分析

    二分图匹配裸题

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define maxn 505050
     5 using namespace std;
     6 
     7 bool vis[maxn];
     8 int matching[maxn],nl,nr,m;
     9 
    10 struct edge{
    11     int from,v;
    12 }e[maxn];
    13 int tot,first[maxn];
    14 void insert(int u,int v){
    15     tot++; e[tot].from = first[u]; e[tot].v = v; first[u] = tot;
    16 }
    17 
    18 int dfs(int now){
    19     for(int i = first[now];i;i = e[i].from){
    20         int v = e[i].v;
    21         if(!vis[v]){
    22             vis[v] = true;
    23             if(!matching[v] || dfs(matching[v])){
    24                 matching[v] = now;
    25                 matching[now] = v;
    26                 return 1;
    27             }
    28         }
    29     }return 0;
    30 }
    31 
    32 int main(){
    33     scanf("%d%d%d",&nl,&nr,&m);
    34     
    35     for(int i = 1;i <= m;i++){
    36         int a,b;
    37         scanf("%d%d",&a,&b);
    38         b += nl;
    39         insert(a,b);
    40         insert(b,a);
    41     }
    42     
    43     int ans = 0;
    44     memset(matching,0,sizeof(matching));
    45     for(int i = 1;i <= nl;i++){
    46         if(!matching[i]){
    47             memset(vis,false,sizeof(vis));
    48             if(dfs(i))
    49                 ++ans;
    50         }
    51     }
    52     
    53     printf("%d
    ",ans);
    54     for(int i = 1;i <= nl;i++){
    55         printf("%d ",max(matching[i]-nl,0));
    56     }
    57     
    58     return 0;
    59 }
    二分图匹配模板
  • 相关阅读:
    Kotlin基本语法笔记3之定义类、继承及创建实例
    Kotlin基本语法笔记2之类型检测及自动类型转换、循环
    Kotlin基本语法笔记之函数、变量的定义及null检测
    C++笔记之外部类访问内部类的私有成员
    正则表达式之不区分大小写的匹配
    springMVC之helloworld
    数组学习
    反射reflect
    JSP学习
    自己做的菜
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7641813.html
Copyright © 2020-2023  润新知