题意: 四个条件 第一 身高相差40以上 第二 性别不同 第三 喜欢的音乐不同 第四 喜欢的运动相同 满足一个 就可以同时去郊游否则不可以。 问最多去多少人?
思路: 我们将男女分开来 就可以建出一个二分图,对于任意的男女生 只要上边四个条件一个也不满足 就表示不能同时去 ,那么我们在其中间连一条边,那么最终的结果就是我们从中取出尽量多的点,使得任意两个点之间没有连线。那么问题就转化成了求最大点独立集。 二分图的最大点独立集= 总点数 - 最大匹配(最小点覆盖)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N =505;
struct node
{
int h;
string mus;
string ball;
};
node _nan[N],_nv[N];
vector<int >ve[N];
int boy[N],girl[N];
int ntot,vtot;
int vis[N];
int dfs(int u)
{
for(int i=0;i<ve[u].size();i++)
{
int v=ve[u][i];
if(!vis[v]){
vis[v]=1;
if( girl[v]==-1||dfs(girl[v]) ){
girl[v]=u;
boy[u]=i;
return 1;
}
}
}
return 0;
}
void xiongyali()
{
int cnt=0;
for(int i=1;i<=ntot;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) cnt++;
}
printf("%d\n",ntot+vtot-cnt);
}
int jud(int i,int j)
{
int h=abs(_nan[i].h-_nv[j].h);
if(h>40) return 0;
if(_nan[i].mus!=_nv[j].mus) return 0;
if(_nan[i].ball==_nv[j].ball) return 0;
return 1;// 两个人不允许同时去。 所以在两个之间建一条边 求最大点独立集
// 也就是 我们取出的图中的任意两个点 不能有边相连
}
int n;
int main()
{
int T;
node tmp;
scanf("%d",&T);
while(T--)
{
cin>>n;
string op;
for(int i=1;i<=n;i++ ) ve[i].clear();
ntot=vtot=0;
for(int i=1;i<=n;i++)
{
cin>>tmp.h>>op>>tmp.mus>>tmp.ball;
if(op[0]=='M') _nan[++ntot]=tmp;
else _nv[++vtot]=tmp;
}
memset(boy,-1,sizeof(boy));
memset(girl,-1,sizeof(girl));
for(int i=1;i<=ntot;i++)
{
for(int j=1;j<=vtot;j++)
{
if(jud(i,j)) ve[i].push_back(j);
}
}
xiongyali();
}
return 0;
}