题意:
有n个人,其中有一些人在一起会搞呢飞起,现在他们要出去玩,求最多能去多少人。
分析:
若两个人会搞呢飞起则他们之间有一条边,转化为求最大独立集问题(二分图。。)。
代码:
#include <iostream>
#include <string>
using namespace std;
const int maxN=512;struct Stu
{int h;string gender,music,sport;
}stu[maxN];int M,v1,v2;
bool g[maxN][maxN];
bool vis[maxN];
int link[maxN];bool dfs(int x)
{for(int y=1;y<=v2;++y) if(g[x][y]&&!vis[y]){vis[y]=true;if(link[y]==0||dfs(link[y])){link[y]=x;return true;}}return false;
}void hungary()
{for(int x=1;x<=v1;++x){memset(vis,false,sizeof(vis));if(dfs(x))++M;} return ;
}int judgeSafe(int i,int j)
{if(abs(stu[i].h-stu[j].h)>40)return 1;if(stu[i].gender==stu[j].gender)return 1;if(stu[i].music!=stu[j].music)return 1;if(stu[i].sport==stu[j].sport)return 1;return 0;
}
int main()
{int cases;cin>>cases;while(cases--){int i,n,j;memset(g,0,sizeof(g));memset(link,0,sizeof(link));scanf("%d",&n);for(i=1;i<=n;++i)cin>>stu[i].h>>stu[i].gender>>stu[i].music>>stu[i].sport;for(i=0;i<=n;++i){for(j=1;j<=n;++j)if(j!=i)if(judgeSafe(i,j)==0)g[i][j]=1;}v1=v2=n;M=0;hungary();printf("%d\n",n-M/2);}return 0;
}