题目连接: 点击打开链接
题意:给你一群人个数p,他们要么喜欢狗讨厌猫,要么喜欢猫讨厌狗,在自己喜欢的动物留下且自己讨厌的动物他们会happy,求管理员最多能让多少人开心 。
思路:求最大独立点集,因此必须求出最大匹配m,关键是建立边,把他们爱好相互矛盾的建立无向边,则解为p-m/2;
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<stack> using namespace std; struct people { bool flag; int like; int hate; }pp[1000]; int f[1000],map[1000][1000],mat[1000]; int n,m,p; void focus()//建立边 { for(int i=0;i<p;i++) { for(int j=i+1;j<p;j++) { if(pp[i].flag!=pp[j].flag) { if(pp[i].hate==pp[j].like||pp[i].like==pp[j].hate) map[i][j]=map[j][i]=1; } } } } int dfs(int u)//用BFS找出相交链(增广路) { int i,t; for(i=0;i<p;i++) { if(!f[i]&&map[u][i]) { f[i]=1; t=mat[i]; if(!t||dfs(t)) { mat[i]=u; return 1; } } } return 0; } int match()//求二分匹配 { int i; int sum=0; memset(mat,0,sizeof(mat)); for(i=0;i<p;i++) { memset(f,0,sizeof(f)); if(dfs(i)) { sum++; } } return sum; } int main() { while(scanf("%d%d%d",&n,&m,&p)!=EOF) { memset(map,0,sizeof(map)); char l,h; int a,b; for(int i=0;i<p;i++) { cin>>l>>a>>h>>b; if(l=='C') { pp[i].flag=true;//标记本人喜爱的动物为猫 pp[i].like=a; pp[i].hate=b; } else { pp[i].flag=false; pp[i].like=a; pp[i].hate=b; } } focus();//建立关系 int ans=match();//求出最大匹配 cout<<p-ans/2<<endl;//最优解 } return 0; }