• 二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041


    最大匹配数就等于最大点覆盖,因为在图里面,凡是要覆盖的点必定是连通的,而最大匹配之后,若还有点没有覆盖到,则必定有新的匹配,与最大匹配数矛盾,如果去掉一些匹配,则必定有点没有覆盖到。

    POJ 1469

    比较简单,用的经典的二分图匹配算法。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int p[500][510],c[500][510];
    int vis[510];
    int lefts[510];
    int cp[500],cc[500],n,m;
    void init()
    {
        memset(vis,0,sizeof vis);
        memset(lefts,-1,sizeof lefts);
        memset(cp,0,sizeof cp);
        memset(cc,0,sizeof cc);
        memset(p,0,sizeof p);
        memset(c,0,sizeof c);
    }
    bool match(int u)
    {
        for (int j=0;j<cp[u];j++){
            int v=p[u][j];
            if (1){
                vis[v]=1;
                if (lefts[v]==-1 || match(lefts[v])){
                    lefts[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while (t--)
        {
            init();
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++){
                int tmp,t2;
                scanf("%d",&tmp);
                for (int j=0;j<tmp;j++){
                    scanf("%d",&t2);
                    p[t2][cp[t2]++]=i;
                    c[i][cc[i]++]=t2;
                }
            }
            int ans=0;
            for (int i=1;i<=m;i++){
                memset(vis,0,sizeof vis);
                if (match(i)) ans++;
            }
            //cout<<ans<<endl;
            if (ans==n) puts("YES");
            else  puts("NO");
    
        }
        return 0;
    }
    

      

    POJ 3041

    最小覆盖问题,转化为求最大匹配

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int mat[510][510],cnt[510];
    int vis[510],lefts[510];
    int n,k;
    bool match(int u)
    {
        for (int i=0;i<cnt[u];i++){
            int v=mat[u][i];
            if (!vis[v]){
                vis[v]=1;
                if (lefts[v]==-1 || match(lefts[v])){
                    lefts[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
    
        while (scanf("%d%d",&n,&k)!=EOF)
        {
            memset(mat,0,sizeof mat);
            memset(cnt,0,sizeof cnt);
            int a,b;
            for (int i=0;i<k;i++){
                scanf("%d%d",&a,&b);
                mat[a][cnt[a]++]=b;
            }
            memset(lefts,-1,sizeof lefts);
            int ans=0;
            for (int i=1;i<=n;i++){
                memset(vis,0,sizeof vis);
                if (match(i)) ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    服务端增加WCF服务全局异常处理机制
    ASP.NET MVC异常处理方案
    [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单
    Asp.Net Mvc的几个小问题
    C# 多线程之Thread类
    C#泛型
    c#public、private、protected、internal、protected internal
    ASP.NET并发处理
    GDB调试器的使用
    【多媒体封装格式详解】---MKV
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3768747.html
Copyright © 2020-2023  润新知