zoukankan      html  css  js  c++  java
  • Guardian of Decency UVALive

    /**
    题目:Guardian of Decency UVALive - 3415 最大独立集=结点数-最大匹配数 老师带大学生旅游
    链接:https://vjudge.net/problem/UVALive-3415
    题意:老师带学生去旅游,要求从n个学生中选出一些学生,满足任意两个学生至少要满足下面的四条中的一条。
    1,身高相差大于40cm
    2,性别相同
    3,最喜欢的音乐不同类型
    4,最喜欢的体育比赛相同类型
    
    输出可以挑选的最多学生人数。
    
    思路:最大独立集做法。
    选出来的学生必须满足上面四个条件至少一个。
    那么如果两个学生都不满足上面的条件,则最多只能从中选一个人。
    
    所以:如果学生a和学生b不满足上面的条件,那么连一条边,题目要求选的学生中,任意两个学生不能有边相连。
    这就是最大独立集(选择尽量多的结点,使得任意一条边的两个端点不会同时被选中)问题。
    
    处理:左边编号为1~n的学生,右边也是编号1~n的学生,相同编号的学生不连边,如果学生a和学生b不满足上面的条件,那么连一条边。
    由于令x为左边的学生编号,y为右边的学生编号(x!=y)
    如果x与y连边,那么y与x也会连一条边,所以边数多了一倍。
    那么最大匹配数也会多一倍。
    本题结果:ans = N-最大匹配数/2:
    
    最大独立集=结点数-最大匹配数。
    
    
    */
    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<vector>
    #include<queue>
    #include<set>
    #include<cstring>
    using namespace std;
    const int MAXN = 505;
    int f[MAXN][MAXN];
    int vit[MAXN], S[MAXN], T[MAXN];
    int N;
    ///模板
    bool Find(int x)///走交替路,寻找增广路
    {
        for(int i = 1; i <= N; i++){///n表示右侧点数。
            if(f[x][i]&&vit[i]==0){
                vit[i] = 1;
                if(T[i]==0||Find(T[i])){
                    T[i] = x;///右边第i个点和左边第x个点匹配成功。
                    S[x] = i;///左边第x个点和右边第i个点匹配成功。
                    return true;
                }
            }
        }
        return false;
    }
    struct node
    {
        int h;
        char sex[2];
        char music[102];
        char sport[102];
    }stu[MAXN];
    int main()
    {
        int n, m, k;
        cin>>k;
        while(k--){
            scanf("%d",&n);
            N = n;
            memset(f, 0, sizeof f);
            for(int i = 1; i <= n; i++){
                scanf("%d%s%s%s",&stu[i].h,stu[i].sex,stu[i].music,stu[i].sport);
            }
            for(int i = 1; i <= n; i++){///每条边都重复了一次。对称。最终匹配数要对半;
                for(int j = 1; j <= n; j++){
                    if(i==j) continue;
                    if(abs(stu[i].h-stu[j].h)<=40&&stu[i].sex[0]!=stu[j].sex[0]&&strcmp(stu[i].music,stu[j].music)==0&&strcmp(stu[i].sport,stu[j].sport)!=0){//都不满足
                        f[i][j] = 1;
                    }
                }
            }
    
            int ans = 0;
            memset(T, 0, sizeof T);
            memset(S, 0, sizeof S);
            ///模板
            for(int i = 1; i <= N; i++){
                memset(vit, 0, sizeof vit);
                if(Find(i)) ans++;
            }
            printf("%d",N-ans/2);
            printf("
    ");
        }
        return  0;
    }
  • 相关阅读:
    jar包的MANIFEST.MF文件
    Spring AOP无法拦截Controller中的方法
    强制更新 Maven缓存库
    【转】深入理解Java:注解(Annotation)--注解处理器
    Java-Method类常用方法详解
    MySQL下查看用户和建立用户
    【转】从零开始玩转logback
    【转】Java日志框架:logback详解
    【转】配置不当引起高危漏洞?看加密货币交易所如何正确用Spring Boot Actuaotr框架
    Spring MVC Junit4 单元測试 JunitTest
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7210753.html
Copyright © 2011-2022 走看看