题目链接:https://vjudge.net/problem/HDU-3829
题目大意:
有\(P\)个小孩,\(N\)只猫,\(M\)只狗。每个小孩都有自己喜欢的某一只宠物和讨厌的某一只宠物(其中必定一只是猫,一只是狗),如果某个小孩喜欢的宠物被留下,而讨厌的宠物被带走,则这个小孩就会很开心。问要留下哪些宠物才能使得开心的小孩最多,求出这个最多的数量。
知识点: 最大独立集
解题思路:
对于两个小孩,如果其中一个喜欢的宠物刚好是另一个讨厌的宠物,那么这两个小孩不能一起开心。将不能一起开心的小孩匹配起来,则最多的开心小孩的数目即为该二分图的最大独立集。
AC代码:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 bool line[510][510],used[510]; 6 int to[510]; 7 struct per{ 8 int like,dislike; 9 }chi[510]; 10 int turn(char s[]){ 11 int len=strlen(s); 12 int ret=0; 13 for(int i=1;i<len;i++){ 14 ret*=10; 15 ret+=s[i]-‘0‘; 16 } 17 if(s[0]==‘C‘) ret+=100; 18 return ret; 19 } 20 bool check(int x,int n){ 21 for(int j=1;j<=n;j++){ 22 if(line[x][j]&&!used[j]){ 23 used[j]=true; 24 if(to[j]==0||check(to[j],n)){ 25 to[j]=x; 26 return true; 27 } 28 } 29 } 30 return false; 31 } 32 int main(){ 33 int N,M,P; 34 char i1[5],i2[5]; 35 while(scanf("%d%d%d",&N,&M,&P)==3){ 36 for(int i=1;i<=P;i++){ 37 for(int j=1;j<=P;j++) line[i][j]=false; 38 to[i]=0; 39 } 40 for(int i=1;i<=P;i++){ 41 scanf("%s %s",i1,i2); 42 chi[i].like=turn(i1); 43 chi[i].dislike=turn(i2); 44 } 45 46 for(int i=1;i<=P;i++){ 47 for(int j=i+1;j<=P;j++){ 48 if(chi[i].like==chi[j].dislike||chi[i].dislike==chi[j].like){ 49 line[i][j]=line[j][i]=true; 50 } 51 } 52 } 53 int all=0; 54 for(int i=1;i<=P;i++){ 55 memset(used,false,sizeof(used)); 56 if(check(i,P)) all++; 57 } 58 printf("%d\n",(2*P-all)/2); 59 } 60 return 0; 61 }