题意:有n只猫,有m只狗。现在有P个学生去参观动物园。每个孩子有喜欢的动物和不喜欢的动物。假如他喜欢猫那么他就一定不喜欢狗(反之亦然)。
如果一个孩子喜欢一个动物,那么这个动物不会被移除,若是不喜欢则移除,这样这个孩子是很高兴的,反之亦然。
现在管理员想知道移除哪些动物可以使最大数量的孩子高兴。
对小孩进行二分匹配。就是把小孩当成点。矛盾的小孩间建立一条边,
最大独立集:在N个点中选出来一个最大点集,使这个点集中的任意两点之间都没有边。所以就是求最大独立集了
最大独立集 == 顶点数 - 最大匹配。
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define N 510 int vis[N], used[N], maps[N][N], p, ans; struct node { char like[N], dislike[N]; }a[N]; bool Find(int u) { for(int i=1; i<=p; i++) { if(!vis[i] && maps[u][i]) { vis[i] = 1; if(!used[i] || Find(used[i])) { used[i] = u; return true; } } } return false; } int main() { int m, n; while(scanf("%d%d%d", &n, &m, &p) != EOF) { memset(maps, 0, sizeof(maps)); for(int i=1; i<=p; i++) { scanf("%s %s", a[i].like, a[i].dislike); for(int j=1; j<i; j++) { if(strcmp(a[i].like, a[j].dislike)==0 || strcmp(a[i].dislike, a[j].like)==0) maps[i][j] = maps[j][i] = 1; } } ans = 0; memset(used, 0, sizeof(used)); for(int i=1; i<=p; i++) { memset(vis, 0, sizeof(vis)); if(Find(i)) ans++; } printf("%d ", p-ans/2); } return 0; }