• 二分图匹配【模板】


    题目描述

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

    输入输出格式

    输入格式:

     

    第一行,n,m,e

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

     

    输出格式:

     

    共一行,二分图最大匹配

     

    输入输出样例

    输入样例
    1 1 1
    1 1
    输出样例
    1

    说明

    n,m1000,1un,1vm

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


    std

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int ans,mp[1001][1001],match[10001];
    bool vis[10001];
    int p,n,m;
    
    bool Hungary(int x){
        for(int i=1;i<=m;++i){
            if(!vis[i] && mp[x][i]){
                vis[i]=true;
                if(!match[i] || Hungary(match[i])){
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=p;++i) {
            int from,to;
            scanf("%d%d",&from,&to);
            if(from>=1&&from<=n && to>=1&&to<=p) 
            mp[from][to]=1;
        }
        for(int i=1;i<=n;++i)
        {
            memset(vis,false,sizeof(vis));
            ans+=Hungary(i);
        }
        printf("%d",ans); 
        return 0;
    }

    mine

    #include<stdio.h>
    #include<string.h>
    using namespace std;
    const int MX=2001;
    struct Edge {
        int to,next;
    }edge[MX*MX];
    bool vis[MX];
    int n,m,e,cnt,first[MX*MX],match[MX];
    
    void read(int &x) {
        x=0;
        int f=1;
        char ch=getchar();
        while (ch<'0'||ch>'9') {
            if (ch=='-') f=-f;
            ch=getchar();
        }
        while (ch>='0'&&ch<='9') {
            x=x*10+ch-48;
            ch=getchar();
        }
        x*=f;
    }
    
    void add(int from,int to)
    {
        edge[++cnt].to=to;
        edge[cnt].next=first[from];
        first[from]=cnt;
    }
    
    bool hungry(int x)
    {
        for(int i=first[x];i;i=edge[i].next)
        {
            int to=edge[i].to;
            if(vis[to]) continue;
            vis[to]=1;
            if(!match[to] || hungry(match[to])) {
                match[to]=x;
                return true;
            }
        }
        return false;
    }
    
    int main()
    {
        read(n),read(m),read(e); 
        for(int i=1;i<=e;++i)
        {
            int sid1,sid2;
            read(sid1),read(sid2);
            if(sid2>m) continue;
            add(sid1,sid2);
        }
        int ans=0;
        for(int i=1;i<=n;++i) {
            memset(vis,0,sizeof(vis));
            ans+=hungry(i); 
        }
        printf("%d",ans);
        return 0;
    } 
    从0到1很难,但从1到100很容易
  • 相关阅读:
    JavaScriptFunction对象(函数)的声明和作用域
    JavaScript常用对象的属性及方法(2)
    html+css>backgroundimg(背景图的设置)
    JavaScript知识点>运算规则与运算(逻辑、位)
    JavaScript知识点:分支结构(if、switch)+算法例题
    JavaScript常用对象的属性及方法(1)
    一些学习js的算法题目
    隐马尔科夫模型
    Eclipse插件开发小结
    二叉树排序和堆排序
  • 原文地址:https://www.cnblogs.com/qseer/p/9636043.html
Copyright © 2020-2023  润新知