HDU 3829 Cat VS Dog
最大独立集: 在N个点的图G中选出m个点,使这m个点两两之间没有边,求m最大值。如果图G满足二分图条件,则可以用二分图匹配来做。最大独立集点数 = N - 最大匹配数。
这里我们将孩子看成A,B集;
如果A喜欢的动物与B不喜欢的动物相同那么我们就连线;我们就认为第i号人与第j号人相冲突,要么选i号,要么选j号;
因此就成了选取最小点覆盖问题,也就是去除最少的人的冲突;
这里要注意就是要建双向边,因为第i号人与第j号人相冲突必然第j号人与第i号人相冲突;
最大独立集点数 = N - 最大匹配数/2。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> using namespace std; bool visit[524],G[524][524]; int match[524]; bool path( int num , int N ) { for( int i = 1 ; i <= N; i ++ ) { if( !visit[i] && G[num][i] ) { visit[i] = true; if( match[i]==0 || path( match[i] ,N ) ) { match[i] = num; return true; } } } return false; } class People { public: string like,dislike; }people[524]; int main( ) { int C,D,N; while( scanf( "%d %d %d",&C,&D ,&N )==3 ) { memset( G ,0 , sizeof( G ) ); memset( match , 0 , sizeof( match ) ); for( int i =1 ; i <= N ; i ++ ) { cin>>people[i].like>>people[i].dislike; } for( int i = 1 ; i <= N ; i++ ) { for( int j = 1 ; j <= N ; j ++ ) { if( people[i].dislike == people[j].like ) { G[i][j] = true; G[j][i] = true; } } } int ans = 0; for( int i = 1 ; i <= N ; i++ ) { memset( visit , 0 , sizeof( visit ) ); if( path( i , N ) ) ans ++; } printf( "%d\n",N - ans/2); } //system( "pause" ); return 0; }