pku 2771 Guardian of Decency

题意:就是一个保守的老师,怕同学们谈恋爱,于是他觉得这样分组是没有问题的

1.身高差距在40厘米以上

2.同性别

3.同样的音乐爱好

4.不同体育爱好

一下注释掉一段话,牢骚,之后正题

/*

话说这题真是命途多舛啊,中午没睡,困死,一看到找朋友,下意识并查集划分集合,写完后怎么也过不了样例

好吧,再读一遍题,瞬间知道是二分匹配- -|||

最后条件又忘写等号了贡献一次WA

*/

思路:题意是求最大独立集,即最大一个集合,其中任意两点之间都不存在边。求法是:最大独立集=顶点数-最大匹配数。

因为我是直接用n个人对n个人匹配的(看了下网上好多用男匹配女的),所以求出的最大匹配数要除2.

这样貌似会比男配女慢一些

/*

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#define nMax 505
using namespace std;
map<string, int> m, s;
struct Student
{
int sport, music;
bool sex;
int high;
}stu[nMax];
bool mat[nMax][nMax], used[nMax];
int maty[nMax], n;

int path(int u)
{
int v;
for(v=0;v<n;v++)
if((mat[u][v])&&(used[v]==0)) {
used[v]=1;
if((maty[v]<0)||(path(maty[v]))) {
maty[v]=u;
return(1);
} // end of if((maty[v]...
} // end of if((mat[u][v]...
return(0);
} // end of int path()

int MaxMatch()
{
int i,ret=0;
memset(maty,-1,sizeof(maty));
for(i=0;i<n;i++){
memset(used,0,sizeof(used));
ret+=path(i);
} // end of if(matx[i]...
return(ret);
}

int main()
{
int music_cnt, sport_cnt, ntime;
scanf("%d", &ntime);
while(ntime--)
{
string sport, music;
char sex;
music_cnt=sport_cnt=1;
m.clear();
s.clear();
memset(mat, 0, sizeof(mat));

scanf("%d", &n);
for(int i=0; i<n; i++)    //输入时顺便把字符串全换成数字
{
cin>>stu[i].high>>sex>>music>>sport;

if(sex=='M') stu[i].sex=1;
else stu[i].sex=0;
if(m[music]==0) m[music]=music_cnt++;
if(s[sport]==0) s[sport]=sport_cnt++;
stu[i].sport=s[sport];
stu[i].music=m[music];
//cout<<m[music]<<" "<<s[sport]<<endl;
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(i==j) continue;
int h=abs(stu[i].high-stu[j].high);
if(stu[i].sex!=stu[j].sex && h<=40 && stu[i].music==stu[j].music && stu[i].sport!=stu[j].sport)
{
mat[i][j]=1;
}
}
}
printf("%d\n", n-MaxMatch()/2);
}
return 0;
}
原文地址:https://www.cnblogs.com/FreeAquar/p/2147370.html