zoukankan      html  css  js  c++  java
  • UVA 12083 POJ 2771 Guardian of Decency

    /*

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=71805#problem/C

    */

    性质:

    【1】二分图最大点独立数=顶点数-二分图的最大匹配

    【2】二分图最小点覆盖数=二分图的最大匹配

    这个题目就是求最大点独立集,根据性质【1】可以求解。

    对于这个问题,我们可以根据性别的不同建立二分图,每两个可能Make Love的人连一条边,o(n*n)的效率可以建图。

    然后跑一遍二分图的最大匹配,答案就出来了。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int MAXN=505;
    int nx,ny;
    int g[MAXN][MAXN];
    int cx[MAXN],cy[MAXN];
    int mk[MAXN];
    int n;
    
    struct People
    {
        int age;
        char sex[5];
        char music[105];
        char sport[105];
    }F[MAXN],M[MAXN];
    
    int path(int u)
    {
        for(int v=0;v<ny;v++)
        {
            if(g[u][v]&&!mk[v])
            {
                mk[v]=1;
                if(cy[v]==-1||path(cy[v]))
                {
                    cx[u]=v;
                    cy[v]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int MaxMatch()
    {
        int res=0;
        memset(cx,-1,sizeof(cx));
        memset(cy,-1,sizeof(cy));
        for(int i=0;i<nx;i++)
        {
            if(cx[i]==-1)
            {
                memset(mk,0,sizeof(mk));
                res=res+path(i);
            }
        }
        return res;
    }
    
    bool ok(People a, People b)
    {
        if(abs(a.age-b.age)<=40&&strcmp(a.music,b.music)==0&&strcmp(a.sport,b.sport)!=0)
            return 1;
        return 0;
    }
    
    int main()
    {
        int T,i,j;
        scanf("%d",&T);
        while(T--)
        {
            nx=0,ny=0;
            memset(g,0,sizeof(g));
    
            scanf("%d",&n);
            
            //建立二分图
            for(i=1;i<=n;i++)
            {
                int age;          char sex[5];
                char music[105];  char sport[105];
                scanf("%d%s%s%s",&age,sex,music,sport);
                if(sex[0]=='M')
                {
                    M[nx].age=age;
                    strcpy(M[nx].sex,sex);
                    strcpy(M[nx].music,music);
                    strcpy(M[nx].sport,sport);
                    nx++;
                }
                else if(sex[0]=='F')
                {
                    F[ny].age=age;
                    strcpy(F[ny].sex,sex);
                    strcpy(F[ny].music,music);
                    strcpy(F[ny].sport,sport);
                    ny++;
                }
            }
            
            for(i=0;i<nx;i++)
                for(j=0;j<ny;j++)
                    if(ok(M[i],F[j]))
                        g[i][j]=1;
                        
            //跑二分图最大匹配,
            //二分图最大点独立数=顶点数-二分图的最大匹配
            //二分图最小点覆盖数=二分图的最大匹配
    
            printf("%d
    ",n-MaxMatch());
        }
        return 0;
    }

     

  • 相关阅读:
    OD: Kernel Vulnerabilities
    newInstance()和new的区别
    原型模式
    工厂模式
    代理模式
    策略模式
    简单工厂模式
    C#操作符的重载
    旅行之舌尖上的中国
    模式和原则[转载]
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4692236.html
Copyright © 2011-2022 走看看