zoukankan      html  css  js  c++  java
  • LA 3415 保守的老师

    题目链接:https://vjudge.net/contest/161820#problem/E

    题意:

    有一些同学,要从中选出一些同学来,人数尽量多,但是,两两之间要满足至少一个条件(身高差>40,性别相同,。。。)

    分析:

    最大独立集:尽量选择多的结点,任意两个结点不相邻;

    男同学X,女同学Y,如果可能产生关系,连一条边,这样这两个人就不会在一起;

    最大独立集=n-最大匹配

    证明:

    最小点覆盖 = 对于每一条边,至少有一个点要被选中

    最大独立集 = 对于每一条边,最多一个点被选中

    从定义中可以看出,这两个是互补的;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 500+5;
     6 
     7 struct BPM {
     8     int n,m;
     9     vector<int> G[maxn];
    10     int left[maxn];
    11     bool T[maxn];
    12 
    13     int right[maxn];
    14     bool S[maxn];
    15 
    16     void init(int n,int m) {
    17         this->n = n;
    18         this->m = m;
    19         for(int i=0;i<n;i++)
    20             G[i].clear();
    21     }
    22 
    23     void AddEdge(int u,int v) {
    24         G[u].push_back(v);
    25     }
    26 
    27     bool match(int u) {
    28         S[u] = true;
    29         for(int i=0;i<G[u].size();i++) {
    30             int v = G[u][i];
    31             if(!T[v]) {
    32                 T[v] = true;
    33                 if(left[v]==-1||match(left[v])) {
    34                     left[v] = u;
    35                     right[u] = v;
    36                     return true;
    37                 }
    38             }
    39         }
    40         return false;
    41     }
    42 
    43     int solve() {
    44         memset(left,-1,sizeof(left));
    45         memset(right,-1,sizeof(right));
    46         int ans = 0;
    47         for(int u=0;u<n;u++) {
    48             memset(S,0,sizeof(S));
    49             memset(T,0,sizeof(T));
    50             if(match(u))
    51                 ans++;
    52         }
    53         return ans;
    54     }
    55 
    56 }sol;
    57 
    58 struct Student {
    59     int h;
    60     string music,sport;
    61     Student(int h,string music,string sport):h(h),music(music),sport(sport) {}
    62 };
    63 
    64 bool conflict(const Student& a,const Student& b) {
    65     return abs(a.h-b.h)<=40&&a.music ==b.music && a.sport!=b.sport;
    66 }
    67 
    68 int main()
    69 {
    70     int t;
    71     cin>>t;
    72     while(t--) {
    73         int n;
    74         cin>>n;
    75         vector<Student> male,female;
    76         for(int i=0;i<n;i++) {
    77             int h;
    78             string gender,music,sport;
    79             cin>>h>>gender>>music>>sport;
    80             if(gender[0]=='M') male.push_back(Student(h,music,sport));
    81             else female.push_back(Student(h,music,sport));
    82         }
    83         int x = male.size();
    84         int y = female.size();
    85         sol.init(x,y);
    86         for(int i=0;i<x;i++)
    87             for(int j=0;j<y;j++)
    88                 if(conflict(male[i],female[j]))
    89                     sol.AddEdge(i,j);
    90         printf("%d
    ",x+y-sol.solve());
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    Mac下使用charles遇到的问题以及解决办法
    webp图片实践之路
    一个粗心的Bug,JSON格式不规范导致AJAX错误
    IE6/7下空div占用空间的问题
    通俗易懂的来讲讲DOM
    Javascript
    简单入门canvas
    HTML5 Boilerplate
    网页字体知识
    备战CKA每日一题——第8天 | initContainer概念、用法、使用场景简介;k8s secret env、volume考题引出
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6804040.html
Copyright © 2011-2022 走看看