1 1 2 C1 D1 D1 C1 1 2 4 C1 D1 C1 D1 C1 D2 D2 C1
1 3HintCase 2: Remove D1 and D2, that makes child 1, 2, 3 happy.
重点不在二分图,重点是怎样看出来这个题用二分图写,或者,怎样去建图,怎样去匹配。。。。
题目只是给出了两个集合,猫,狗,还有剩下一群人,可是建图的过程却是建立在人上面的。。。。
需要注意的是这一题不是喜欢狗就是喜欢猫,所以是个非常明显的二分图,所以是建立在二分图上的最大独立集,所以用最大独立集数=顶点数-最大匹配数。如果构不成二分图,是不能用最大匹配来解决的,求非二分图的最大独立集相当于求其补图最大团。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include<string.h> #include<algorithm> #include<math.h> #include<queue> using namespace std; typedef long long ll; const int N=555; bool tu[N][N]; int from[N];///记录右边的点如果配对好了它来自哪里 bool use[N];///记录右边的点是否已经完成了配对 int n,m;///m,n分别表示两边的各自数量,n是左边,m是右边 bool dfs(int x) { for(int i=1;i<=m;i++)///m是右边,所以这里上界是m if(!use[i]&&tu[x][i]) { use[i]=1; if(from[i]==-1||dfs(from[i])) { from[i]=x; return 1; } } return 0; } int hungary() { int tot=0; memset(from,-1,sizeof(from)); for(int i=1;i<=n;i++)///n是左边,所以这里上界是n { memset(use,0,sizeof(use)); if(dfs(i)) tot++; } return tot; } char x1[505],x2[505];int t1[505],t2[505]; int main() { int M,N,p; while(cin>>N>>M>>p) { m=n=p; memset(tu,0,sizeof(tu)); for(int i=1;i<=p;i++) { scanf(" %c%d %c%d",&x1[i],&t1[i],&x2[i],&t2[i]); for(int j=0;j<i;j++) if(x1[j]==x2[i]&&t1[j]==t2[i]) tu[i][j]=tu[j][i]=1; else if(x2[j]==x1[i]&&t2[j]==t1[i]) tu[i][j]=tu[j][i]=1; } printf("%d\n",p-hungary()/2); } return 0; }