sicily 11192. Guardian of Decency(二分匹配)

题意是老师要带学生出游,但有怕学生会成为一对。给出学生们不会成为一对的条件:
1身高相差超过40
2性别相同
3音乐风格不一样
4最喜欢的运动一样

然后给出每个学生的资料,问能带多少学生出去,使得这些学生不会成为一对。

构图时先求出会成为一对的对数ans,然后总数n-ans/2就是答案。


#include <iostream>
#include <cstring>
#include <string>

using namespace std;
const int MAX = 505;
struct student
{
int h; char sex; string style,sport;
}stu[MAX];
int map[MAX][MAX],match[MAX];
bool vis[MAX];
int t,n;

int can(int i,int j)
{
if(stu[i].h - stu[j].h > 40 || stu[j].h - stu[i].h > 40) return 0;
if(stu[i].sex == stu[j].sex) return 0;
if(stu[i].style != stu[j].style) return 0;
if(stu[i].sport == stu[j].sport) return 0;

return 1;
}

bool findPath(int k)
{
for(int i = 1;i <= n;++i)
{
if(map[k][i] && !vis[i])
{
vis[i] = true;

if(match[i] == false || findPath(match[i]))
{
match[i] = k;
return true;
}
}
}
return false;
}


int main()
{
int i,j;

cin>>t;

while(t--)
{
cin>>n;

for(i = 1;i <= n;++i)
{
cin>>stu[i].h>>stu[i].sex>>stu[i].style>>stu[i].sport;
}

for(i = 1;i <= n;++i)
{
for(j = 1;j <= n;++j)
{
if(i != j) map[i][j] = can(i,j);
else map[i][j] = 0;
}
}

memset(match,0,sizeof(match));
int ans = 0;

for(i = 1;i <= n;++i)
{
memset(vis,false,sizeof(vis));

if(findPath(i)) ans++;
}

cout<<n-ans/2<<endl;
}

return 0;
}

你可能感兴趣的:(DI)