zoukankan      html  css  js  c++  java
  • 二分图最大匹配(匈牙利算法)

    题目背景

    二分图

    题目描述

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

    输入输出格式

    输入格式:

    第一行,n,m,e

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

    输出格式:

    共一行,二分图最大匹配

    输入输出样例

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

    说明

    n,m<=1000,1<=u<=n,1<=v<=m

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

    算法:二分图匹配

    增广路定义:从一个未被选中的点出发,依次经过非匹配边,匹配边,非匹配边,匹配边……,

     如果终点是一个未被选择的点,则为增广路。

    这里讲一下我的理解:

       在一个增广路中,非匹配边总比匹配边多一条。那么,对于一种已匹配好的情况,如果

    能找出一条增广路,那么原情况就不是最优的,替换它。如此下去,就能找出二分图的最大匹配。

    所以,对于1……n的点,每次都DFS一下是否有增广路,如果有,答案+1。

       个人感觉这种算法是比较妙的,虽然没有网络流跑的快,但有一定的思维深度(还是画画图更好理解)

    #include<set>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define INF 2147483647
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,e,f[2000][2000],link[2000],vis[2000];
    //f表示左右是否有边
    //link[i]表示当前的最大匹配中,右边的i对应的点
    //vis[i]表示当前这个点是否匹配过了,所以要每次都更新
    int dfs(int x){ for(int i=1;i<=m;++i) if(!vis[i]&&f[x][i]){ //注意顺序,常数优化,不然会TLE vis[i]=1; if(!link[i]||dfs(link[i])){ link[i]=x; return 1; } } return 0; } int main(){ n=read();m=read();e=read(); while(e--){ int x,y;x=read();y=read(); f[x][y]=1; } int ans=0; for(int i=1;i<=n;++i){ memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d",ans); return 0; }

    https://www.luogu.org/problem/show?pid=3386

  • 相关阅读:
    PythonのTkinter基本原理
    使用 Word (VBA) 分割长图到多页
    如何使用 Shebang Line (Python 虚拟环境)
    将常用的 VBScript 脚本放到任务栏 (Pin VBScript to Taskbar)
    关于 VBScript 中的 CreateObject
    Windows Scripting Host (WSH) 是什么?
    Component Object Model (COM) 是什么?
    IOS 打开中文 html 文件,显示乱码的问题
    科技发展时间线(Technology Timeline)
    列置换密码
  • 原文地址:https://www.cnblogs.com/hanyu20021030/p/6530729.html
Copyright © 2011-2022 走看看