题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2768
/*
求的是最多能满足多少个人,所以map存的是人的情况。
最大独立集=顶点数-最大匹配。
最小点覆盖=最大匹配
如果A和B的选择有矛盾,则AB之间有条路径,
然后求最小点覆盖,用最少的点覆盖所有路径,
剩余的点就是答案。
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int map[510][510],x[510],y[510],vis[510],vote[510],unvote[510];
int t,c,d,m;
bool dfs(int i)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]&&!vis[j])
{
vis[j]=1;
if(!y[j]||dfs(y[j]))
{
y[j]=i;
x[i]=j;
return 1;
}
}
}
return 0;
}
int match()
{
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
int ans=0;
for(int i=1;i<=m;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
ans++;
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&c,&d,&m);
memset(map,0,sizeof(map));
memset(vote,0,sizeof(vote));
memset(unvote,0,sizeof(unvote));
int i,j;
for(i=1;i<=m;i++)
{
char s1,s2;
int a,b;
getchar();
scanf("%c%d %c%d",&s1,&a,&s2,&b);
if(s1=='C') vote[i]=a;
else vote[i]=c+a;
if(s2=='C') unvote[i]=b;
else unvote[i]=c+b;
}
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
{
if(vote[i]==unvote[j]||unvote[i]==vote[j])
map[i][j]=1;
}
printf("%d\n",m-match()/2);
}
return 0;
}