<题目链接>
题目大意:
动物园有n条狗。m头猫。p个小孩,每一个小孩有一个喜欢的动物和讨厌的动物。如今动物园要转移一些动物。假设一个小孩喜欢的动物在,不喜欢的动物不在,他就会happy。问动物最多能使几个小孩happy。
解题分析:
因为本题不同的小孩之间喜好可能会产生冲突,所以,要使最多的小孩满意,不妨将这些冲突的小孩之间相互连线,然后求出不产生冲突的最大点集,于是本题就转化为了最大独立集问题。最大独立集=总点数-最大匹配数。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <string> 5 #include <cstring> 6 #include <vector> 7 using namespace std; 8 9 const int M=1505; 10 int match[M]; 11 bool vis[M]; 12 vector<int>map[M]; 13 string lk[M],dislk[M]; 14 int n,m,p,uN; 15 bool dfs(int u){ 16 for(int i=0;i<map[u].size();i++){ 17 if(!vis[map[u][i]]){ 18 vis[map[u][i]]=true; 19 if(match[map[u][i]]==-1||dfs(match[map[u][i]])){ 20 match[map[u][i]]=u; 21 return true; 22 } 23 } 24 } 25 return false; 26 } 27 int hungary(){ 28 int res=0; 29 memset(match,-1,sizeof(match)); 30 for(int u=0;u<p;u++){ 31 memset(vis,false,sizeof(vis)); 32 res+=dfs(u); 33 } 34 return res; 35 } 36 int main(){ 37 while(scanf("%d%d%d",&n,&m,&p)!=EOF){ 38 for(int i=0;i<M;i++)map[i].clear(); 39 for(int i=0;i<p;i++){ 40 cin>>lk[i]>>dislk[i]; 41 } 42 for(int i=0;i<p;i++) 43 for(int j=i+1;j<p;j++) 44 if(lk[i]==dislk[j]||dislk[i]==lk[j]){ //产生矛盾的人之间建立无向边 45 map[i].push_back(j); 46 map[j].push_back(i); 47 } 48 printf("%d ",p-hungary()/2); //最大独立集=总点数-最大匹配 49 } 50 return 0; 51 }
2018-11-16