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
  • 相关阅读:
    Dapper ORM 用法—Net下无敌的ORM(转)
    微軟将从 .NET 4 以后的版本弃用 System.Data.OracleClient 以及Oracle 的各种连接方法
    最火的.NET开源项目
    sql日期格式化
    项目失败总结
    C#,往线程里传参数的方法总结
    线程的几种用法
    小程序api-01-abcdefg
    cnpm
    关于mpvue和wafer2-client-sdk的 微信登录失败,请检查网络状态
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6804040.html
Copyright © 2011-2022 走看看