二分图最大独立集,裸题
题目意思:
有k 个学生,学生有男女,某些男女之间有些可能谈恋爱。老师要带一些学生出去
旅游,要求不能有男女之间谈恋爱。
本题要点:
1、k <= 500, 用邻接矩阵来存图。
左部节点: n个男学生
右部节点: m个女学生。
2、老师要带尽可能多的学生出去,就是取的点尽量多,显然是二分图最大独立集。
二分图最大独立集 = 顶点个数 - 二分图最大匹配
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
const int MaxN = 510, MaxLen = 110;
int a[MaxN][MaxN], match[MaxN];
bool vis[MaxN];
int T, n, m, k;struct stu
{
int h;char sex[2], music[MaxLen], sport[MaxLen];
}boys[MaxN], girls[MaxN];bool dfs(int x)
{
for(int y = 1; y <= m; ++y){
if(!a[x][y] || vis[y])continue;vis[y] = true;if(!match[y] || dfs(match[y])){
match[y] = x;return true;}}return false;
}void solve()
{
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(abs(boys[i].h - girls[j].h) > 40 || strcmp(boys[i].music, girls[j].music) != 0|| strcmp(boys[i].sport, girls[j].sport) == 0){
a[i][j] = 0; }else{
a[i][j] = 1;}}}int ans = 0;for(int i = 1; i <= n; ++i){
memset(vis, false, sizeof vis);if(dfs(i))++ans;}printf("%d\n", n + m - ans);
}int main()
{
int height;char ch[2];scanf("%d", &T);while(T--){
memset(a, 0, sizeof a);memset(match, 0, sizeof match);n = m = 0;scanf("%d", &k);while(k--){
scanf("%d%s", &height, ch); if(ch[0] == 'M'){
boys[++n].h = height;strcpy(boys[n].sex, ch);scanf("%s%s", boys[n].music, boys[n].sport);}else{
girls[++m].h = height; strcpy(girls[m].sex, ch);scanf("%s%s", girls[m].music, girls[m].sport);}}solve();}return 0;
}/* 2 4 35 M classicism programming 0 M baroque skiing 43 M baroque chess 30 F baroque soccer 8 27 M romance programming 194 F baroque programming 67 M baroque ping-pong 51 M classicism programming 80 M classicism Paintball 35 M baroque ping-pong 39 F romance ping-pong 110 M romance Paintball *//* 3 7 */