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。

 

View Code
#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;
}

 

 

 

posted @ 2012-07-05 15:25  wutaoKeen  阅读(168)  评论(0编辑  收藏  举报