题意

Frank是一个思想有些保守的高中老师。有一次,他需要带一些学生出去旅行,但又怕其中一些学生在旅行中萌生爱意。为了降低这种事情发生的概率,他决定确保带出去的任意两个学生至少要满足下面四条中的一条。

1.身高相差大于40厘米

2.性别相同

3.最喜欢的音乐属于不同类型

4.最喜欢的体育比赛相同

你的任务是帮助Frank挑选尽量多的学生,使得任意两个学生至少满足上述条件中的一条。

分析

这个模型叫二分图的最大独立集。既选择尽量多的结点,使得任意两个结点不相邻(既任意一条边的两个端点不会被同时选中)。最大独立集与最小覆盖是互补的,因此答案就是结点总数减去最大匹配数。

建模:将每个人看作一个结点,如果两个人四个条件都不满足,就意味着他们不能同时被选择,连一条无向边。这样,问题就转换为求这个图的最大独立集。因为他们每个人不是男生就是女生,所以这个图是二分图。

按照惯例,我依然是用网络流来做的最大匹配。原因依然是不会KM···等哪天(8012年)我学会来并且心情好可能会来补一下KM的代码。

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue> using namespace std;
const int maxn=+;
const int maxm=+; const int INF=;
struct Dinic{
int head[maxn],Next[maxm],to[maxm],cap[maxm],flow[maxm];
int sz,n,m,s,t;
bool vis[maxn];
int cur[maxn],d[maxn];
void init(int n){
this->n=n;
memset(head,-,sizeof(head));
this->sz=-;
}
void add_edge(int a,int b,int c){
++sz;
to[sz]=b;
cap[sz]=c;flow[sz]=;
Next[sz]=head[a];head[a]=sz;
++sz;
to[sz]=a;
cap[sz]=c;flow[sz]=c;
Next[sz]=head[b];head[b]=sz;
}
bool BFS(){
memset(vis,,sizeof(vis));
queue<int>Q;
vis[s]=;
d[s]=;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(!vis[v]&&cap[i]>flow[i]){
vis[v]=;
d[v]=d[u]+;
Q.push(v);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==)return a;
int Flow=,f;
for(int& i=cur[x];i!=-;i=Next[i]){
int v=to[i];
if(d[v]==d[x]+&&(f=DFS(v,min(a,cap[i]-flow[i])))>){
Flow+=f;
flow[i]+=f;
flow[i^]-=f;
a-=f;
if(a==)break;
}
}
return Flow;
}
int Maxflow(int s,int t){
this->s=s,this->t=t;
int Flow=;
while(BFS()){
for(int i=;i<=n;i++)
cur[i]=head[i]; Flow+=DFS(s,INF);
}
return Flow;
}
}dinic;
int T,n;
int high[maxn];
char sex[maxn];
string mus[maxn],phy[maxn];
int main(){
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d %c",&high[i],&sex[i]);
cin>>mus[i]>>phy[i];
}
dinic.init(n+);
for(int i=;i<=n;i++){
if(sex[i]=='M'){
for(int j=;j<=n;j++){
if(sex[j]=='F'&&abs(high[i]-high[j])<=&&mus[i]==mus[j]&&phy[i]!=phy[j]){
dinic.add_edge(i,j,);
}
}
}
}
for(int i=;i<=n;i++){
if(sex[i]=='M')
dinic.add_edge(,i,);
}
for(int i=;i<=n;i++){
if(sex[i]=='F')
dinic.add_edge(i,n+,);
}
int ans=dinic.Maxflow(,n+);
printf("%d\n",n-ans);
}
return ;
}

其实我觉得这道题不知道这个模型只是考虑最小割的话也能想。去除最少的学生使得剩下的所有学生之间任意两个之间都满足四个条件中的一条。我们在学生之间连的边是这两个学生间只能选一个或者都不选,那个割掉这条边就代表去掉这两个学生中的一个。所以可以求出最小割来以后,用总的人数n减掉最小割。

哇万能的最小割我感觉这样想比背什么模型好多了啊!

【LA3415 训练指南】保守的老师 【二分图最大独立集,最小割】的更多相关文章

  1. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...

  2. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  3. 二分图&网络流&最小割等问题的总结

    二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...

  4. hdu 1569 &1565 (二分图带权最大独立集 - 最小割应用)

    要选出一些点,这些点之间没有相邻边且要求权值之和最大,求这个权值 分析:二分图带权最大独立集. 用最大流最小割定理求解.其建图思路是:将所有格点编号,奇数视作X部,偶数视作Y部,建立源点S和汇点T, ...

  5. 【LA4043 训练指南】蚂蚁 【二分图最佳完美匹配,费用流】

    题意 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接一条线段. 分析 结点分黑白,很容易想到二分图.其中每个白点对应一个X结 ...

  6. 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)

    layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...

  7. 【UVA11419 训练指南】我是SAM 【二分图最小覆盖,最小割】

    题意 给出一个R*C大小的网格,网格上面放了一些目标.可以在网格外发射子弹,子弹会沿着垂直或者水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算最少需要多少子弹,各从哪些位置发射,才能把所有目 ...

  8. 【LA3523 训练指南】圆桌骑士 【双连通分量】

    题意 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防赞同和反 ...

  9. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

随机推荐

  1. Google Chrome 总提示flash插件过期,用命令行模式解决

    目标那改成:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --allow-outdate ...

  2. ibernate+Struts2环境如何使用jqGrid。

    因为公司项目需要,在Hibernate+Struts2的环境下,研究了一下如何使用jqGrid. 说实在的,Struts2+jqGrid不是一个很好的组合.因为jqGrid中很多功能,基本上都使用的是 ...

  3. 6.Python使用Pandas小案例

    1.使用以下命令引入Pandas和xlrd,引入成功后在pycharm的setting导入即可使用(pip3是由于个人python版本为3.6)==在dos命令行输入以下信息 pip3 install ...

  4. RK3288 添加WiFi&BT模块AP6212

    CPU:RK3288 系统:Android 5.1 注:系统中自带的模块没有AP6212,相近的只有AP6210,设置为AP6210,直接添加固件也可以正常使用. 此文是手动添加AP6212的例程. ...

  5. 【转载】Leaflet 中文api

    L.Map API各种类中的核心部分,用来在页面中创建地图并操纵地图. 使用 example // initialize the map on the "map" div with ...

  6. ubuntu :扩充虚拟机的磁盘容量

    前言: 开始建立虚拟机的时候给的容量是20G,给了10G的交换空间,所以后来有点不够用了,现在安装软件会出现提示磁盘空间不足,所以需要扩充一下磁盘的容量. 步骤:     1.因为我用的是Vmware ...

  7. MOSS 2013研究系列---修改默认Logo

    开发SharePoint2013 的时候,系统里面有一个“SharePoint” 的logo,客户很少不满意,我们的系统不能出现产品的名称,如下图: 咋么修改呢,咨询了广大网友,给出了一个解决方案: ...

  8. android 手机UDP 接受不到数据

    一.有的手机不能直接接收UDP包,可能是手机厂商在定制Rom的时候把这个功能给关掉了. 1.可先在oncreate()方法里面实例化一个WifiManager.MulticastLock 对象lock ...

  9. mysql 优化(3)

    using filesort 不能利用索引来进行分组或排序,利用filesort算法在内存或者磁盘进行排序using temporary 先在内存中进行分组,归并等操作,不够利用磁盘 SELECT i ...

  10. JNI的一个简单实例

    本例子使用的操作系统MacOS, 64位JVM. JNI编写的几个步骤如下: 编写Java代码,并注明native方法: public class HelloJni { public native v ...