题目:
题意:
共有c只猫和d条狗,还有v个人,每个人都有一只喜欢的猫/狗以及一直讨厌的猫/狗,喜欢猫的人一定讨厌的是狗,喜欢狗的人也一定讨厌的是猫,现可以淘汰一部分猫狗,使得一部分人得到满足(即喜欢的动物被留下而讨厌的动物被淘汰),问最多可以使多少个人得到满足。
分析:
将其视为一个二分图,两边分别是喜欢猫和狗的人,将有冲突关系的两人连边(喜欢的动物是对方讨厌的动物的两人视为有冲突关系,两人显然是无法同时被满足的),再跑一遍最大独立集就好了。
最大独立集=点数-最大匹配
代码:
#include<bits/stdc++.h>
using namespace std;
int c,d,n,match[505];
vector<int>nbr[505];
int vis[505];
bool dfs(int cur,int tot){
for(int i=0;i<nbr[cur].size();++i){
int nxt=nbr[cur][i];
if(vis[nxt]!=tot){
vis[nxt]=tot;
if(!match[nxt]||dfs(match[nxt],tot)){
match[nxt]=cur;
return 1;
}
}
}
return 0;
}
struct node{
string like,hate;
}person[505];
int main(){
while(cin>>c>>d>>n){
for(int i=1;i<=n;++i){
cin>>person[i].like>>person[i].hate;
nbr[i].clear();
}
memset(match,0,sizeof(match));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(i==j)continue;
if(person[i].like==person[j].hate||person[j].like==person[i].hate){
if(person[i].like[0]=='C')nbr[i].push_back(j);
else nbr[j].push_back(i);
}
}
}
int ans=0;
for(int i=1;i<=n;++i)ans+=dfs(i,i);
cout<<n-ans<<'\n';
}
return 0;
}