• P3386 【模板】二分图匹配 -网络流版


                二分图匹配

    题目背景

    二分图

    感谢@一扶苏一 提供的hack数据

    题目描述

    给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

    输入输出格式

    输入格式:

    第一行,n,m,e

    第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

    输出格式:

    共一行,二分图最大匹配

    输入输出样例

    输入样例#1: 复制
    1 1 1
    1 1
    输出样例#1: 复制
    1

    说明

    n,m leq 1000n,m1000 , 1 leq u leq n1un , 1 leq v leq m1vm

    因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。

    算法:二分图匹配

    思路


     

    dinic跑二分图最大流

    一个源点(0)连接1到n

    一个汇点(n+m+1)连接n+1到n+m

    套上板子就可以了


     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <queue>
     5 #define inf 0x3f3f3f3f
     6 #define maxn 2010001
     7 using namespace std;
     8 
     9 int n,m,s,t;
    10 struct node{
    11     int v,next,cap;
    12 }e[maxn];
    13 int head[maxn],tot=1;
    14 int dis[maxn];
    15 
    16 void add_node(int a,int b,int c)
    17 {
    18     e[++tot]=(node){b,head[a],c};
    19     head[a]=tot;
    20 }
    21 
    22 bool bfs()
    23 {
    24     memset(dis,-1,sizeof(dis));
    25     queue<int> q;
    26     q.push(s);
    27     dis[s]=0;
    28     while(!q.empty()) {
    29         int x=q.front();
    30         q.pop();
    31         for(int i=head[x];i;i=e[i].next)
    32         {
    33             int v=e[i].v;
    34             if(e[i].cap&&dis[v]==-1) 
    35             {
    36                 dis[v]=dis[x]+1;
    37                 q.push(v);
    38             }
    39         } 
    40     }
    41     return dis[t]!=-1;
    42 }
    43 
    44 int dfs(int now,int f)
    45 {
    46     if(now==t) return f;
    47     int rest=f;
    48     for(int i=head[now];i;i=e[i].next)
    49     {
    50         int v=e[i].v;
    51         if(e[i].cap&&rest&&dis[v]==dis[now]+1)
    52         {
    53             int t=dfs(v,min(rest,e[i].cap));
    54             if(!t) dis[v]=0;
    55             e[i].cap-=t;
    56             e[i^1].cap+=t;
    57             rest-=t; 
    58         }
    59     } 
    60     return f-rest;
    61 } 
    62 
    63 void dinic()
    64 {
    65     int ans=0;
    66     while(bfs())
    67         ans+=dfs(s,inf);
    68     printf("%d",ans);
    69 }
    70 
    71 int main()
    72 {
    73       int ee;
    74       scanf("%d%d%d",&n,&m,&ee);
    75     int x,y;
    76     for(int i=1;i<=ee;++i) {
    77         scanf("%d%d",&x,&y);
    78         if(x>n||y>m) continue;
    79         add_node(x,y+n,1);
    80         add_node(y+n,x,0);
    81     }
    82     s=0;t=n+1+m;
    83     for(int i=1;i<=n;++i) {
    84         add_node(s,i,1);
    85         add_node(i,s,0);
    86     }
    87     for(int i=1;i<=m;++i) {
    88         add_node(n+i,t,1);
    89         add_node(t,n+i,0);
    90     }
    91        dinic();
    92     return 0;
    93 }
  • 相关阅读:
    MSSQL—列记录合并
    MSSQL—字符串分离(Split函数)
    如何在ASP.NET Core中自定义Azure Storage File Provider
    从零开始实现ASP.NET Core MVC的插件式开发(六)
    对ASP.NET程序员非常有用的85个工具
    vs-code 配置
    idea-plugin
    VirtualBox中CentOS遇到的问题
    监听器
    线程组复杂场景
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9270548.html
Copyright © 2020-2023  润新知